diff options
author | Sean Griffin <sean@thoughtbot.com> | 2015-06-12 11:00:27 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2015-06-12 11:03:12 -0600 |
commit | 07b4078eb664dd45b1526a85358574ea8e669ce3 (patch) | |
tree | 27160010746fb8134ebb1262be0dd97605c05b8b /activerecord/lib/active_record/attribute_methods | |
parent | 8beb328befa53d74fe9c7942ddb188563bd4de33 (diff) | |
download | rails-07b4078eb664dd45b1526a85358574ea8e669ce3.tar.gz rails-07b4078eb664dd45b1526a85358574ea8e669ce3.tar.bz2 rails-07b4078eb664dd45b1526a85358574ea8e669ce3.zip |
Don't crash when mutating attributes in a getter
If a getter has side effects on the DB, `changes_applied` will be called
twice. The second time will try and remove the changed attributes cache,
and will crash because it's already been unset. This also demonstrates
that we shouldn't assume that calling getters won't change the value of
`changed_attributes`, and we need to clear the cache if an attribute is
modified.
Fixes #20531.
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods')
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/dirty.rb | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb index 7ba907f786..0171ef3bdf 100644 --- a/activerecord/lib/active_record/attribute_methods/dirty.rb +++ b/activerecord/lib/active_record/attribute_methods/dirty.rb @@ -108,6 +108,7 @@ module ActiveRecord end def save_changed_attribute(attr, old_value) + clear_changed_attributes_cache if attribute_changed_by_setter?(attr) clear_attribute_changes(attr) unless _field_changed?(attr, old_value) else @@ -176,7 +177,11 @@ module ActiveRecord @cached_changed_attributes = changed_attributes yield ensure - remove_instance_variable(:@cached_changed_attributes) + clear_changed_attributes_cache + end + + def clear_changed_attributes_cache + remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes) end end end |