Sonntag, 13. April 2014

Soft delete your ActiveRecord!

Some models should not be deleted, but deactivated for very comprehensible reasons:
  1. Restoring the record
  2. Documenting the record in pre deletion points in time
  3. Statistics
The migration for adding the new boolean 'active' column to the Person model:
rails g migration add_active_to_people active:boolean
and running rails db:migrate. The model:
class Person < ActiveRecord::Base
  attr_accessible :name
  validates :active, :inclusion => { :in => [true, false] }
  before_validation :activate, 
    :on => :create,
    :if => {|r| }

    where :active => true

  def activate = true

  def deactivate = false
The model expects the boolean active flag to be set with nothing else than true or false.
Furthermore every new person record will be initialized with true in a callback before validating it. That means if nothing else was set, the instance method activate is called, which does exactly set the flag to true by default.
A named scope appends a selection to the finder chain, returning all active people. A usage example:
If you are not familiar with ActiveRecord scopes read 'Scope the model!'.
The second instance method deactivate deactivates the record. In fact it prepares soft deletion by setting the 'active' flag to false like:
and touching he database:
which will generate the SQL on a MariaDB system:
UPDATE 'people' SET 'active' = 0, WHERE 'people'.'id' = 1
Well that could be wrapped behind:
def deactivate!!
Another reasonable data type for soft deletion columns is datetime like deleted_at. I would suggest using it, when the timestamp of the deletion has to be documented as well.

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17