class ZombieRecord::Restorable::WithDeletedAssociations

Wraps a deleted record and makes sure that any associated record is available even if it is deleted. This is done by intercepting the method calls, checking if the method is an association access, and then ensuring that deleted records are included in the resulting query.

Public Class Methods

new(record) click to toggle source
# File lib/zombie_record/restorable.rb, line 91
def initialize(record)
  @record = record
end

Public Instance Methods

method_missing(name, *args, &block) click to toggle source
# File lib/zombie_record/restorable.rb, line 95
def method_missing(name, *args, &block)
  delegate_to_record(name) { @record.public_send(name, *args, &block) }
end

Private Instance Methods

associated_record_class(reflection) click to toggle source
# File lib/zombie_record/restorable.rb, line 124
def associated_record_class(reflection)
  # Polymorphic associations don't have an easy way to access the class,
  # so we'll have to do it ourselves.
  if reflection.options[:polymorphic]
    @record.public_send(reflection.foreign_type).constantize
  else
    reflection.klass
  end
end
delegate_to_record(name, &block) click to toggle source
# File lib/zombie_record/restorable.rb, line 108
def delegate_to_record(name, &block)
  if reflection = reflect_on(name)
    with_deleted_associations(reflection, &block)
  else
    block.call
  end
end
reflect_on(name) click to toggle source
# File lib/zombie_record/restorable.rb, line 116
def reflect_on(name)
  reflection = @record.class.reflect_on_association(name)

  if reflection && restorable_reflection?(reflection)
    reflection
  end
end
restorable_reflection?(reflection) click to toggle source
# File lib/zombie_record/restorable.rb, line 134
def restorable_reflection?(reflection)
  associated_record_class(reflection).ancestors.include?(Restorable)
end
with_deleted_associations(reflection, &block) click to toggle source
# File lib/zombie_record/restorable.rb, line 138
def with_deleted_associations(reflection, &block)
  case reflection.macro
  when :has_one, :belongs_to
    associated_record_class(reflection).unscoped(&block).with_deleted_associations
  when :has_many
    block.call.with_deleted
  else
    raise "invalid macro #{reflection.macro.inspect}"
  end
end