diff options
Diffstat (limited to 'activemodel/lib/active_model/dirty.rb')
-rw-r--r-- | activemodel/lib/active_model/dirty.rb | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index b89b98feed..c5f1b3f11a 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -14,13 +14,9 @@ module ActiveModel # track. # * Call <tt>attr_name_will_change!</tt> before each change to the tracked # attribute. - # - # If you wish to also track previous changes on save or update, you need to - # add: - # - # @previously_changed = changes - # - # inside of your save or update method. + # * Call <tt>changes_applied</tt> after the changes are persisted. + # * Call <tt>reset_changes</tt> when you want to reset the changes + # information. # # A minimal implementation could be: # @@ -39,14 +35,18 @@ module ActiveModel # end # # def save - # @previously_changed = changes - # @changed_attributes.clear + # # do persistence work + # changes_applied + # end + # + # def reload! + # reset_changes # end # end # # A newly instantiated object is unchanged: # - # person = Person.find_by_name('Uncle Bob') + # person = Person.find_by(name: 'Uncle Bob') # person.changed? # => false # # Change the name: @@ -65,6 +65,12 @@ module ActiveModel # person.changed? # => false # person.name_changed? # => false # + # Reset the changes: + # + # person.previous_changes # => {"name" => ["Uncle Bob", "Bill"]} + # person.reload! + # person.previous_changes # => {} + # # Assigning the same value leaves the attribute unchanged: # # person.name = 'Bill' @@ -91,7 +97,7 @@ module ActiveModel included do attribute_method_suffix '_changed?', '_change', '_will_change!', '_was' - attribute_method_affix :prefix => 'reset_', :suffix => '!' + attribute_method_affix prefix: 'reset_', suffix: '!' end # Returns +true+ if any attribute have unsaved changes, +false+ otherwise. @@ -129,7 +135,7 @@ module ActiveModel # person.save # person.previous_changes # => {"name" => ["bob", "robert"]} def previous_changes - @previously_changed + @previously_changed ||= {} end # Returns a hash of the attributes with unsaved changes indicating their original @@ -142,11 +148,28 @@ module ActiveModel @changed_attributes ||= ActiveSupport::HashWithIndifferentAccess.new end + # Handle <tt>*_changed?</tt> for +method_missing+. + def attribute_changed?(attr) + changed_attributes.include?(attr) + end + + # Handle <tt>*_was</tt> for +method_missing+. + def attribute_was(attr) + attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) + end + private - # Handle <tt>*_changed?</tt> for +method_missing+. - def attribute_changed?(attr) - changed_attributes.include?(attr) + # Removes current changes and makes them accessible through +previous_changes+. + def changes_applied + @previously_changed = changes + @changed_attributes = {} + end + + # Removes all dirty data: current changes and previous changes + def reset_changes + @previously_changed = {} + @changed_attributes = {} end # Handle <tt>*_change</tt> for +method_missing+. @@ -154,11 +177,6 @@ module ActiveModel [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr) end - # Handle <tt>*_was</tt> for +method_missing+. - def attribute_was(attr) - attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) - end - # Handle <tt>*_will_change!</tt> for +method_missing+. def attribute_will_change!(attr) return if attribute_changed?(attr) |