Module: ActiveRecord::TrackDirtyAssociations::ClassMethods

Defined in:
lib/activerecord/track_dirty_associations.rb

Instance Method Summary collapse

Instance Method Details

#track_dirty_associations(*association_types) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
69
70
71
# File 'lib/activerecord/track_dirty_associations.rb', line 9

def track_dirty_associations *association_types
  klass = self

  klass.send :after_save, -> { dirty_assocs = {} }

  klass.singleton_class.send :alias_method, :old_has_many, :has_many

  klass.singleton_class.send :define_method, :has_many do |*args, **opts|
    association_type = args.first
    options = opts
    if association_types.empty? || association_types.include?(association_type)
      create_association_methods association_type
      options.merge!({
        after_add: ->(object, association) { add_association association_type, object, association },
        before_remove: ->(object, association) { remove_association association_type, object, association }
      })
    end
    old_has_many *args, options
  end

  klass.singleton_class.send :alias_method, :old_has_one, :has_one

  klass.singleton_class.send :define_method, :has_one do |*args, **opts|
    association_type = args.first
    options = opts
    if association_types.empty? || association_types.include?(association_type)
      create_association_methods association_type
    end
    old_has_one *args, options
  end

  klass.singleton_class.send :alias_method, :old_belongs_to, :belongs_to

  klass.singleton_class.send :define_method, :belongs_to do |*args, **opts|
    association_type = args.first
    options = opts
    if association_types.empty? || association_types.include?(association_type)
      create_association_methods association_type
    end
    old_belongs_to *args, options
  end

  klass.singleton_class.send :define_method, :belongs_to do |*args, **opts|
    association_type = args.first
    options = opts
    if association_types.empty? || association_types.include?(association_type)
      create_association_methods association_type
    end
    old_belongs_to *args, options
  end

  define_method 'dirty_associations' do
    dirty_associations = dirty_assocs || {}
    association_types.each do |association_type|
      dirty_associations[association_type] = association_changes(association_type) if association_changes(association_type).any?
    end
    dirty_associations
  end

  define_method 'dirty_associations?' do
    send(:dirty_associations).any?
  end
end