Sha256: 38160d76770742cd82537ae2ca59aa91f5d6b4a23d01aaea4a05106bf634990a

Contents?: true

Size: 1.93 KB

Versions: 2

Compression:

Stored size: 1.93 KB

Contents

require 'active_record'
require 'soft_deletion/version'
require 'soft_deletion/dependency'

module SoftDeletion
  def self.included(base)
    unless base.ancestors.include?(ActiveRecord::Base)
      raise "You can only include this if #{base} extends ActiveRecord::Base"
    end
    base.extend(ClassMethods)
    base.send(:default_scope, :conditions => base.soft_delete_default_scope_conditions)

    # backport after_soft_delete so we can safely upgrade to rails 3
    if ActiveRecord::VERSION::MAJOR > 2
      base.define_callbacks :soft_delete
      class << base
        def after_soft_delete(*callbacks)
          set_callback :soft_delete, :after, *callbacks
        end
      end
    else
      base.define_callbacks :after_soft_delete
    end
  end

  module ClassMethods
    def soft_delete_default_scope_conditions
      {:deleted_at => nil}
    end

    def soft_delete_dependents
      self.reflect_on_all_associations.
        select { |a| [:destroy, :delete_all, :nullify].include?(a.options[:dependent]) }.
        map(&:name)
    end

    def with_deleted
      with_exclusive_scope do
        yield self
      end
    end
  end

  def deleted?
    deleted_at.present?
  end

  def mark_as_deleted
    self.deleted_at = Time.now
  end

  def mark_as_undeleted
    self.deleted_at = nil
  end

  def soft_delete!
    self.class.transaction do
      if ActiveRecord::VERSION::MAJOR > 2
        run_callbacks :soft_delete do
          _soft_delete!
        end
      else
        _soft_delete!
        run_callbacks :after_soft_delete
      end
    end
  end

  def soft_undelete!
    self.class.transaction do
      mark_as_undeleted
      soft_delete_dependencies.each(&:soft_undelete!)
      save!
    end
  end

  protected

  def _soft_delete!
    mark_as_deleted
    soft_delete_dependencies.each(&:soft_delete!)
    save!
  end

  def soft_delete_dependencies
    self.class.soft_delete_dependents.map { |dependent| Dependency.new(self, dependent) }
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
soft_deletion-0.1.3 lib/soft_deletion.rb
soft_deletion-0.1.2 lib/soft_deletion.rb