module ActiveRecord::AttributeMethods::Dirty
Public Instance Methods
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
# File lib/active_record/attribute_methods/dirty.rb, line 165 def attribute_before_last_save(attr_name) mutations_before_last_save.original_value(attr_name) end
# File lib/active_record/attribute_methods/dirty.rb, line 219 def attribute_change(*) emit_warning_if_needed("attribute_change", "saved_change_to_attribute") super end
Alias for `attribute_change`
# File lib/active_record/attribute_methods/dirty.rb, line 185 def attribute_change_to_be_saved(attr_name) mutations_from_database.change_to_attribute(attr_name) end
# File lib/active_record/attribute_methods/dirty.rb, line 224 def attribute_changed?(*) emit_warning_if_needed("attribute_changed?", "saved_change_to_attribute?") super end
Alias for `attribute_was`
# File lib/active_record/attribute_methods/dirty.rb, line 190 def attribute_in_database(attr_name) mutations_from_database.original_value(attr_name) end
# File lib/active_record/attribute_methods/dirty.rb, line 214 def attribute_was(*) emit_warning_if_needed("attribute_was", "attribute_before_last_save") super end
Alias for `changed_attributes`
# File lib/active_record/attribute_methods/dirty.rb, line 210 def attributes_in_database changes_to_save.transform_values(&:first) end
# File lib/active_record/attribute_methods/dirty.rb, line 234 def changed(*) emit_warning_if_needed("changed", "saved_changes.keys") super end
# File lib/active_record/attribute_methods/dirty.rb, line 229 def changed?(*) emit_warning_if_needed("changed?", "saved_changes?") super end
Alias for `changed`
# File lib/active_record/attribute_methods/dirty.rb, line 205 def changed_attribute_names_to_save changes_to_save.keys end
Alias for `changes`
# File lib/active_record/attribute_methods/dirty.rb, line 200 def changes_to_save mutations_from_database.changes end
Alias for `changed?`
# File lib/active_record/attribute_methods/dirty.rb, line 195 def has_changes_to_save? mutations_from_database.any_changes? end
reload
the record and clears changed attributes.
# File lib/active_record/attribute_methods/dirty.rb, line 48 def reload(*) super.tap do @previous_mutation_tracker = nil clear_mutation_trackers @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new end end
Attempts to save
the record and clears changed attributes if
successful.
# File lib/active_record/attribute_methods/dirty.rb, line 33 def save(*) if status = super changes_applied end status end
Attempts to save!
the record and clears changed attributes if
successful.
# File lib/active_record/attribute_methods/dirty.rb, line 41 def save!(*) super.tap do changes_applied end end
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”)`
# File lib/active_record/attribute_methods/dirty.rb, line 157 def saved_change_to_attribute(attr_name) mutations_before_last_save.change_to_attribute(attr_name) end
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
# File lib/active_record/attribute_methods/dirty.rb, line 144 def saved_change_to_attribute?(attr_name, **options) mutations_before_last_save.changed?(attr_name, **options) end
Returns a hash containing all the changes that were just saved.
# File lib/active_record/attribute_methods/dirty.rb, line 175 def saved_changes mutations_before_last_save.changes end
Did the last call to `save` have any changes to change?
# File lib/active_record/attribute_methods/dirty.rb, line 170 def saved_changes? mutations_before_last_save.any_changes? end
Alias for `attribute_changed?`
# File lib/active_record/attribute_methods/dirty.rb, line 180 def will_save_change_to_attribute?(attr_name, **options) mutations_from_database.changed?(attr_name, **options) end
Private Instance Methods
# File lib/active_record/attribute_methods/dirty.rb, line 295 def _create_record(*) partial_writes? ? super(keys_for_partial_write) : super end
# File lib/active_record/attribute_methods/dirty.rb, line 291 def _update_record(*) partial_writes? ? super(keys_for_partial_write) : super end
# File lib/active_record/attribute_methods/dirty.rb, line 276 def attribute_will_change!(attr_name) super if self.class.has_attribute?(attr_name) mutations_from_database.force_change(attr_name) else ActiveSupport::Deprecation.warn(" #{attr_name} is not an attribute known to Active Record. This behavior is deprecated and will be removed in the next version of Rails. If you'd like #{attr_name} to be managed by Active Record, add `attribute :#{attr_name} to your class. ".squish) mutations_from_database.deprecated_force_change(attr_name) end end
# File lib/active_record/attribute_methods/dirty.rb, line 321 def cache_changed_attributes @cached_changed_attributes = changed_attributes yield ensure clear_changed_attributes_cache end
# File lib/active_record/attribute_methods/dirty.rb, line 267 def changes_include?(attr_name) super || mutation_tracker.changed?(attr_name) end
# File lib/active_record/attribute_methods/dirty.rb, line 271 def clear_attribute_change(attr_name) mutation_tracker.forget_change(attr_name) mutations_from_database.forget_change(attr_name) end
# File lib/active_record/attribute_methods/dirty.rb, line 328 def clear_changed_attributes_cache remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes) end
# File lib/active_record/attribute_methods/dirty.rb, line 307 def clear_mutation_trackers @mutation_tracker = nil @mutations_from_database = nil @mutations_before_last_save = nil end
# File lib/active_record/attribute_methods/dirty.rb, line 248 def emit_warning_if_needed(method_name, new_method_name) unless mutation_tracker.equal?(mutations_from_database) ActiveSupport::Deprecation.warn(" The behavior of `#{method_name}` inside of after callbacks will be changing in the next version of Rails. The new return value will reflect the behavior of calling the method after `save` returned (e.g. the opposite of what it returns now). To maintain the current behavior, use `#{new_method_name}` instead. ".squish) end end
# File lib/active_record/attribute_methods/dirty.rb, line 303 def forget_attribute_assignments @attributes = @attributes.map(&:forgetting_assignment) end
# File lib/active_record/attribute_methods/dirty.rb, line 299 def keys_for_partial_write changed_attribute_names_to_save & self.class.column_names end
# File lib/active_record/attribute_methods/dirty.rb, line 241 def mutation_tracker unless defined?(@mutation_tracker) @mutation_tracker = nil end @mutation_tracker ||= AttributeMutationTracker.new(@attributes) end
# File lib/active_record/attribute_methods/dirty.rb, line 317 def mutations_before_last_save @mutations_before_last_save ||= previous_mutation_tracker end
# File lib/active_record/attribute_methods/dirty.rb, line 260 def mutations_from_database unless defined?(@mutations_from_database) @mutations_from_database = nil end @mutations_from_database ||= mutation_tracker end
# File lib/active_record/attribute_methods/dirty.rb, line 313 def previous_mutation_tracker @previous_mutation_tracker ||= NullMutationTracker.instance end