Module: ActiveRecord::AttributeMethods::Dirty

Extended by:
ActiveSupport::Concern
Includes:
ActiveModel::Dirty
Defined in:
activerecord/lib/active_record/attribute_methods/dirty.rb

Constant Summary

Constants included from ActiveModel::AttributeMethods

ActiveModel::AttributeMethods::CALL_COMPILABLE_REGEXP, ActiveModel::AttributeMethods::NAME_COMPILABLE_REGEXP

Instance Method Summary collapse

Methods included from ActiveSupport::Concern

append_features, class_methods, extended, included

Methods included from ActiveModel::Dirty

#attribute_changed?, #attribute_previously_changed?, #attribute_was, #changed, #changed?, #restore_attributes

Methods included from ActiveModel::AttributeMethods

#attribute_missing, #method_missing, #respond_to?, #respond_to_without_attributes?

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class ActiveModel::AttributeMethods

Instance Method Details

#attribute_before_last_save(attr_name) ⇒ Object

Returns the original value of an attribute before the last save. Behaves similarly to attribute_was. This method is useful in after callbacks to get the original value of an attribute before the save that just occurred



130
131
132
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 130

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end

#attribute_change_to_be_saved(attr_name) ⇒ Object

Alias for attribute_change



150
151
152
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 150

def attribute_change_to_be_saved(attr_name)
  mutations_from_database.change_to_attribute(attr_name)
end

#attribute_changed_in_place?(attr_name) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


92
93
94
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 92

def attribute_changed_in_place?(attr_name) # :nodoc:
  mutation_tracker.changed_in_place?(attr_name)
end

#attribute_in_database(attr_name) ⇒ Object

Alias for attribute_was



155
156
157
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 155

def attribute_in_database(attr_name)
  mutations_from_database.original_value(attr_name)
end

#attributes_in_databaseObject

Alias for changed_attributes



175
176
177
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 175

def attributes_in_database
  changes_to_save.transform_values(&:first)
end

#changed_attribute_names_to_saveObject

Alias for changed



170
171
172
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 170

def changed_attribute_names_to_save
  changes_to_save.keys
end

#changed_attributesObject

:nodoc:



72
73
74
75
76
77
78
79
80
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 72

def changed_attributes # :nodoc:
  # This should only be set by methods which will call changed_attributes
  # multiple times when it is known that the computed value cannot change.
  if defined?(@cached_changed_attributes)
    @cached_changed_attributes
  else
    super.reverse_merge(mutation_tracker.changed_values).freeze
  end
end

#changesObject

:nodoc:



82
83
84
85
86
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 82

def changes # :nodoc:
  cache_changed_attributes do
    super
  end
end

#changes_appliedObject

:nodoc:



50
51
52
53
54
55
56
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 50

def changes_applied # :nodoc:
  @mutations_before_last_save = mutation_tracker
  @mutations_from_database = AttributeMutationTracker.new(@attributes)
  @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
  forget_attribute_assignments
  clear_mutation_trackers
end

#changes_to_saveObject

Alias for changes



165
166
167
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 165

def changes_to_save
  mutations_from_database.changes
end

#clear_attribute_changes(attr_names) ⇒ Object

:nodoc:



65
66
67
68
69
70
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 65

def clear_attribute_changes(attr_names) # :nodoc:
  super
  attr_names.each do |attr_name|
    clear_attribute_change(attr_name)
  end
end

#clear_changes_informationObject

:nodoc:



58
59
60
61
62
63
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 58

def clear_changes_information # :nodoc:
  @mutations_before_last_save = nil
  @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
  forget_attribute_assignments
  clear_mutation_trackers
end

#has_changes_to_save?Boolean

Alias for changed?

Returns:

  • (Boolean)


160
161
162
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 160

def has_changes_to_save?
  mutations_from_database.any_changes?
end

#initialize_dup(other) ⇒ Object

:nodoc:



42
43
44
45
46
47
48
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 42

def initialize_dup(other) # :nodoc:
  super
  @attributes = self.class._default_attributes.map do |attr|
    attr.with_value_from_user(@attributes.fetch_value(attr.name))
  end
  clear_mutation_trackers
end

#previous_changesObject

:nodoc:



88
89
90
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 88

def previous_changes # :nodoc:
  mutations_before_last_save.changes
end

#reloadObject

reload the record and clears changed attributes.



34
35
36
37
38
39
40
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 34

def reload(*)
  super.tap do
    @mutations_before_last_save = nil
    clear_mutation_trackers
    @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
  end
end

#saved_change_to_attribute(attr_name) ⇒ Object

Returns the change to an attribute during the last save. If the attribute was changed, the result will be an array containing the original value and the saved value.

Behaves similarly to attribute_change. This method is useful in after callbacks, to see the change in an attribute that just occurred

This method can be invoked as saved_change_to_name in instead of saved_change_to_attribute("name")



122
123
124
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 122

def saved_change_to_attribute(attr_name)
  mutations_before_last_save.change_to_attribute(attr_name)
end

#saved_change_to_attribute?(attr_name, **options) ⇒ Boolean

Did this attribute change when we last saved? This method can be invoked as saved_change_to_name? instead of saved_change_to_attribute?("name"). Behaves similarly to attribute_changed?. This method is useful in after callbacks to determine if the call to save changed a certain attribute.

Options

from When passed, this method will return false unless the original value is equal to the given option

to When passed, this method will return false unless the value was changed to the given value

Returns:

  • (Boolean)


109
110
111
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 109

def saved_change_to_attribute?(attr_name, **options)
  mutations_before_last_save.changed?(attr_name, **options)
end

#saved_changesObject

Returns a hash containing all the changes that were just saved.



140
141
142
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 140

def saved_changes
  mutations_before_last_save.changes
end

#saved_changes?Boolean

Did the last call to save have any changes to change?

Returns:

  • (Boolean)


135
136
137
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 135

def saved_changes?
  mutations_before_last_save.any_changes?
end

#will_save_change_to_attribute?(attr_name, **options) ⇒ Boolean

Alias for attribute_changed?

Returns:

  • (Boolean)


145
146
147
# File 'activerecord/lib/active_record/attribute_methods/dirty.rb', line 145

def will_save_change_to_attribute?(attr_name, **options)
  mutations_from_database.changed?(attr_name, **options)
end