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 164 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 218 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 184 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 223 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 189 def attribute_in_database(attr_name) mutations_from_database.original_value(attr_name) end
# File lib/active_record/attribute_methods/dirty.rb, line 213 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 209 def attributes_in_database changes_to_save.transform_values(&:first) end
# File lib/active_record/attribute_methods/dirty.rb, line 233 def changed(*) emit_warning_if_needed("changed", "saved_changes.keys") super end
# File lib/active_record/attribute_methods/dirty.rb, line 228 def changed?(*) emit_warning_if_needed("changed?", "saved_changes?") super end
Alias for `changed`
# File lib/active_record/attribute_methods/dirty.rb, line 204 def changed_attribute_names_to_save changes_to_save.keys end
Alias for `changes`
# File lib/active_record/attribute_methods/dirty.rb, line 199 def changes_to_save mutations_from_database.changes end
Alias for `changed?`
# File lib/active_record/attribute_methods/dirty.rb, line 194 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 156 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 143 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 174 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 169 def saved_changes? mutations_before_last_save.any_changes? end
Alias for `attribute_changed?`
# File lib/active_record/attribute_methods/dirty.rb, line 179 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 294 def _create_record(*) partial_writes? ? super(keys_for_partial_write) : super end
# File lib/active_record/attribute_methods/dirty.rb, line 290 def _update_record(*) partial_writes? ? super(keys_for_partial_write) : super end
# File lib/active_record/attribute_methods/dirty.rb, line 275 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 320 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 266 def changes_include?(attr_name) super || mutation_tracker.changed?(attr_name) end
# File lib/active_record/attribute_methods/dirty.rb, line 270 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 327 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 306 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 247 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 302 def forget_attribute_assignments @attributes = @attributes.map(&:forgetting_assignment) end
# File lib/active_record/attribute_methods/dirty.rb, line 298 def keys_for_partial_write changed_attribute_names_to_save & self.class.column_names end
# File lib/active_record/attribute_methods/dirty.rb, line 240 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 316 def mutations_before_last_save @mutations_before_last_save ||= previous_mutation_tracker end
# File lib/active_record/attribute_methods/dirty.rb, line 259 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 312 def previous_mutation_tracker @previous_mutation_tracker ||= NullMutationTracker.instance end