Module: PaperTrail::ActiveRecordExt::OrDeleted::ClassMethods

Defined in:
lib/paper_trail/active_record/or_deleted.rb

Instance Method Summary collapse

Instance Method Details

#define_assoc_or_deleted(assoc_name, suffix: 'or_deleted') ⇒ Object

Defines a {association}_or_deleted method for the given association. This method will call the usual association method to try to find the associated record but if that returns nil, will fall back to looking for a deleted record from the versions history (using klass.find_deleted).

You can replace the or_deleted part with a different suffix using suffix: option.

You can even give it the same name as the existing association method if you want to override the existing method with one that always falls back to looking for a deleted record.

class Post belongs_to :author # overrides author method with a version that finds deleted if not found define_assoc_or_deleted :author, suffix: nil



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/paper_trail/active_record/or_deleted.rb', line 37

def define_assoc_or_deleted(assoc_name, suffix: 'or_deleted')
  reflection = reflect_on_association(assoc_name) or raise(ArgumentError, "can't find reflection for #{assoc_name}")
  method_name = suffix ? "#{assoc_name}_#{suffix}" : assoc_name
  #begin
  #  puts "Creating #{self.name}.#{method_name}  =>  #{reflection.klass}.find_deleted(#{reflection.foreign_key})"

  prepend(Module.new do
    define_method method_name do |*args|
      orig_value =
        if defined?(super)
          super(*args)
        else
          public_send(reflection.name, *args)
        end
      return orig_value if orig_value

      klass =
        if reflection.polymorphic?
          public_send(reflection.foreign_type)&.constantize
        else
          reflection.klass
        end
      id = public_send(reflection.foreign_key)

      klass&.find_deleted(id) if id
    end
  end)

  #rescue
  #  puts "Rescued for #{self.name}.#{reflection.inspect}: #{$!} from #{$!.backtrace.first(5)}"
  #end
end

#define_assoc_or_deleted_on_all_associations(suffix: 'or_deleted') ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/paper_trail/active_record/or_deleted.rb', line 70

def define_assoc_or_deleted_on_all_associations(suffix: 'or_deleted')
  reflect_on_all_associations.each do |reflection|
    #puts %(#{self}.reflection.name=#{(reflection.name).inspect})
    next if reflection.collection?

    assoc_name = reflection.name
    method_name = suffix ? "#{assoc_name}_#{suffix}" : assoc_name
    next if method_defined?(method_name)

    define_assoc_or_deleted reflection.name, suffix: suffix
  end
end