diff options
-rw-r--r-- | activemodel/lib/active_model/dirty.rb | 29 | ||||
-rw-r--r-- | activerecord/CHANGELOG.md | 5 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_many_association.rb | 2 |
3 files changed, 21 insertions, 15 deletions
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index ed00d8cf12..ca04f48c1c 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -114,7 +114,7 @@ module ActiveModel include ActiveModel::AttributeMethods included do - attribute_method_suffix '_changed?', '_change', '_will_change!', '_was', '_was=' + attribute_method_suffix '_changed?', '_change', '_will_change!', '_was' attribute_method_affix prefix: 'reset_', suffix: '!' attribute_method_affix prefix: 'restore_', suffix: '!' end @@ -180,26 +180,13 @@ module ActiveModel attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) end - # Handle <tt>*_was=</tt> for +method_missing+ - def attribute_was=(attr, old_value) - attributes_changed_by_setter[attr] = old_value - end - alias_method :set_attribute_was, :attribute_was= - # Restore all previous data of the provided attributes. def restore_attributes(attributes = changed) attributes.each { |attr| restore_attribute! attr } end - # Remove changes information for the provided attributes. - def clear_attribute_changes(attributes) - attributes_changed_by_setter.except!(*attributes) - end - private - alias_method :attributes_changed_by_setter, :changed_attributes # :nodoc: - # Removes current changes and makes them accessible through +previous_changes+. def changes_applied # :doc: @previously_changed = changes @@ -249,5 +236,19 @@ module ActiveModel clear_attribute_changes([attr]) end end + + # This is necessary because `changed_attributes` might be overridden in + # other implemntations (e.g. in `ActiveRecord`) + alias_method :attributes_changed_by_setter, :changed_attributes # :nodoc: + + # Force an attribute to have a particular "before" value + def set_attribute_was(attr, old_value) + attributes_changed_by_setter[attr] = old_value + end + + # Remove changes information for the provided attributes. + def clear_attribute_changes(attributes) + attributes_changed_by_setter.except!(*attributes) + end end end diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 02660ae4c2..495e9c77d7 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,8 @@ +* `*_was` and `changes` now work correctly for in-place attribute changes as + well. + + *Sean Griffin* + * Fix regression on after_commit that didnt fire when having nested transactions. Fixes #16425 diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index cf59699228..1413efaf7f 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -103,7 +103,7 @@ module ActiveRecord if has_cached_counter?(reflection) counter = cached_counter_attribute_name(reflection) owner[counter] += difference - owner.clear_attribute_changes([counter]) # eww + owner.send(:clear_attribute_changes, counter) # eww end end |