Module: PaperTrail::ActiveRecordExt::BaseExtensions::ClassMethods

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

Instance Method Summary collapse

Instance Method Details

#find_deleted(id) ⇒ Object

Unlike find, does not raise RecordNotFound if not found



31
32
33
# File 'lib/paper_trail/active_record/base_extensions.rb', line 31

def find_deleted(id)
  find_deleted_version(id)&.reify
end

#find_deleted!(id) ⇒ Object



35
36
37
# File 'lib/paper_trail/active_record/base_extensions.rb', line 35

def find_deleted!(id)
  find_deleted_version!(id).reify
end

#find_deleted_version(id) ⇒ Object



22
23
24
# File 'lib/paper_trail/active_record/base_extensions.rb', line 22

def find_deleted_version(id)
  Version.destroys.with_item_keys(base_class.name, id).first
end

#find_deleted_version!(id) ⇒ Object



26
27
28
# File 'lib/paper_trail/active_record/base_extensions.rb', line 26

def find_deleted_version!(id)
  Version.destroys.with_item_keys(base_class.name, id).first!
end

#has_many_versions(name, *args, **options) ⇒ Object



53
54
55
# File 'lib/paper_trail/active_record/base_extensions.rb', line 53

def has_many_versions(name, *args, **options)
  has_many name, *args, class_name: 'Version', extend: PaperTrail::ActiveRecordExt.config.versions_extends, **options
end

Creates associations for finding related versions — that is, versions for related/children records of this record, not just versions of this record itself.

The way it finds those related associations is by querying the versions table on a "metadata" column, for example user_id, instead of on item_id (which is what you use to get versions directly for a particular record).

foreign_key identifies which metadata column links versions for related/child records back to the "parent" record.

For example, to create a :versions_with_related association on User that finds all versions that have changed a particular user record or any of its related/child records, configure paper_trail for all related/child models with meta: :user_id, and then pass :user_id as the foreign_key to has_related_versions.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/paper_trail/active_record/base_extensions.rb', line 72

def has_related_versions(foreign_key, item_types: nil)
  parent_model_name = name
  with_options(foreign_key: foreign_key) do |_|
    if item_types
      # self + filtered related records
      _.has_many_versions :versions_with_related, -> { where(arel_table[:item_type].in([parent_model_name] + item_types)) }
      #        filtered related records only (exclude self)
      _.has_many_versions :related_versions,      -> { where(arel_table[:item_type].in(                      item_types)) }
      has_versions_with_all_related foreign_key, 'all_'
    else
      # Not filtered by item_types, so just make the "all" association be the default instead of
      # defining 2 associations that are identical.
      has_versions_with_all_related foreign_key, ''
    end
  end
end


89
90
91
92
93
94
95
96
97
# File 'lib/paper_trail/active_record/base_extensions.rb', line 89

def has_versions_with_all_related(foreign_key, all_prefix)
  parent_model_name = name
  with_options(foreign_key: foreign_key) do |_|
    # self + all related records (any item_type)
    _.has_many_versions :"versions_with_#{all_prefix}related"
    #        all related records *only* (exclude self)
    _.has_many_versions :"#{all_prefix}related_versions", -> { where(arel_table[:item_type].not_eq(parent_model_name)) }
  end
end

#valid_versions_association_namesObject



39
40
41
42
43
44
45
46
47
48
# File 'lib/paper_trail/active_record/base_extensions.rb', line 39

def valid_versions_association_names
  [
    :versions,
    :versions_with_related,
    :versions_with_all_related,

    :related_versions,
    :all_related_versions,
  ]
end

#versions(subclasses: true) ⇒ Object

Versions for STI subclasses are included by default. Pass subclasses: false to only include versions for the base class (no subclasses).



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/paper_trail/active_record/base_extensions.rb', line 10

def versions(subclasses: true)
  if self == base_class and subclasses
    Version.where(item_type: base_class.name)
  else
    Version.where(item_type: base_class.name, item_subtype: self.name)
  end.tap do |versions|
    PaperTrail::ActiveRecordExt.config.versions_extends.each do |mod|
      versions.extend(mod)
    end
  end
end

#versions_association_namesObject



49
50
51
# File 'lib/paper_trail/active_record/base_extensions.rb', line 49

def versions_association_names
  reflect_on_all_associations.map(&:name).grep(/versions/)
end