module ActiveModel::Dirty
def attribute_change(attr)
def attribute_change(attr) [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr) end
def attribute_changed?(attr, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN) # :nodoc:
Handles *_changed? for +method_missing+.
def attribute_changed?(attr, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN) # :nodoc: !!changes_include?(attr) && (to == OPTION_NOT_GIVEN || to == __send__(attr)) && (from == OPTION_NOT_GIVEN || from == changed_attributes[attr]) end
def attribute_previous_change(attr)
def attribute_previous_change(attr) previous_changes[attr] if attribute_previously_changed?(attr) end
def attribute_previously_changed?(attr) #:nodoc:
Handles *_previously_changed? for +method_missing+.
def attribute_previously_changed?(attr) #:nodoc: previous_changes_include?(attr) end
def attribute_was(attr) # :nodoc:
Handles *_was for +method_missing+.
def attribute_was(attr) # :nodoc: attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) end
def attribute_will_change!(attr)
def attribute_will_change!(attr) return if attribute_changed?(attr) begin value = __send__(attr) value = value.duplicable? ? value.clone : value rescue TypeError, NoMethodError end set_attribute_was(attr, value) end
def changed
person.name = 'bob'
person.changed # => []
Returns an array with the name of the attributes with unsaved changes.
def changed changed_attributes.keys end
def changed?
person.name = 'bob'
person.changed? # => false
Returns +true+ if any of the attributes have unsaved changes, +false+ otherwise.
def changed? changed_attributes.present? end
def changed_attributes
person.name = 'robert'
person.name # => "bob"
values like attr => original value.
Returns a hash of the attributes with unsaved changes indicating their original
def changed_attributes @changed_attributes ||= ActiveSupport::HashWithIndifferentAccess.new end
def changes
person.name = 'bob'
person.changes # => {}
and new values like attr => [original value, new value].
Returns a hash of changed attributes indicating their original
def changes ActiveSupport::HashWithIndifferentAccess[changed.map { |attr| [attr, attribute_change(attr)] }] end
def changes_applied # :doc:
Removes current changes and makes them accessible through +previous_changes+.
def changes_applied # :doc: @previously_changed = changes @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new end
def changes_include?(attr_name)
def changes_include?(attr_name) attributes_changed_by_setter.include?(attr_name) end
def clear_attribute_changes(attributes) # :doc:
Remove changes information for the provided attributes.
def clear_attribute_changes(attributes) # :doc: attributes_changed_by_setter.except!(*attributes) end
def clear_changes_information # :doc:
Clears all dirty data: current changes and previous changes.
def clear_changes_information # :doc: @previously_changed = ActiveSupport::HashWithIndifferentAccess.new @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new end
def previous_changes
person.save
person.name = 'robert'
person.name # => "bob"
Returns a hash of attributes that were changed before the model was saved.
def previous_changes @previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new end
def previous_changes_include?(attr_name)
Returns +true+ if attr_name were changed before the model was saved,
def previous_changes_include?(attr_name) previous_changes.include?(attr_name) end
def restore_attribute!(attr)
def restore_attribute!(attr) if attribute_changed?(attr) __send__("#{attr}=", changed_attributes[attr]) clear_attribute_changes([attr]) end end
def restore_attributes(attributes = changed)
def restore_attributes(attributes = changed) attributes.each { |attr| restore_attribute! attr } end
def set_attribute_was(attr, old_value)
def set_attribute_was(attr, old_value) attributes_changed_by_setter[attr] = old_value end