module ZombieRecord::Restorable

Public Instance Methods

deleted?() click to toggle source

Whether the record has been destroyed.

Returns true if the record is deleted, false otherwise.

# File lib/zombie_record/restorable.rb, line 30
def deleted?
  !deleted_at.nil?
end
restore!() click to toggle source

Restores a destroyed record.

Returns nothing.

# File lib/zombie_record/restorable.rb, line 14
def restore!
  if frozen?
    raise "cannot restore an object that has been destroyed directly; " <<
          "please make sure to load it from the database again."
  end

  run_callbacks :restore do
    update_column(:deleted_at, nil)

    restore_associated_records!
  end
end
with_deleted_associations() click to toggle source

Allows accessing deleted associations from the record.

Example

book = Book.first.with_deleted_associations

# Even deleted chapters are returned!
book.chapters #=> [...]

Returns a wrapped ActiveRecord::Base object.

# File lib/zombie_record/restorable.rb, line 44
def with_deleted_associations
  if deleted?
    WithDeletedAssociations.new(self)
  else
    self
  end
end

Private Instance Methods

deleted_records_for_association(association) click to toggle source
# File lib/zombie_record/restorable.rb, line 71
def deleted_records_for_association(association)
  if association.macro == :has_one
    foreign_key = association.foreign_key
    association.klass.deleted.where(foreign_key => id)
  elsif association.macro == :has_many
    public_send(association.name).deleted
  elsif association.macro == :belongs_to
    associated_id = public_send(association.foreign_key)
    return [] unless associated_id.present?
    association.klass.deleted.where(:id => associated_id)
  else
    raise "association type #{association.macro} not supported"
  end
end
restore_associated_records!() click to toggle source
# File lib/zombie_record/restorable.rb, line 54
def restore_associated_records!
  self.class.reflect_on_all_associations.each do |association|
    # Only restore associations that are automatically destroyed alongside
    # the record.
    next unless association.options[:dependent] == :destroy

    # Don't try to restore models that are not restorable.
    next unless association.klass.ancestors.include?(Restorable)

    records = deleted_records_for_association(association)

    records.each do |record|
      record.restore!
    end
  end
end