From 07b4078eb664dd45b1526a85358574ea8e669ce3 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Fri, 12 Jun 2015 11:00:27 -0600 Subject: 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. --- activerecord/test/cases/dirty_test.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'activerecord/test/cases/dirty_test.rb') diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index 216f228142..f5aaf22e13 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -703,6 +703,22 @@ class DirtyTest < ActiveRecord::TestCase assert pirate.catchphrase_changed?(from: "arrrr", to: "arrrr matey!") end + test "getters with side effects are allowed" do + klass = Class.new(Pirate) do + def catchphrase + if super.blank? + update_attribute(:catchphrase, "arr") # what could possibly go wrong? + end + super + end + end + + pirate = klass.create!(catchphrase: "lol") + pirate.update_attribute(:catchphrase, nil) + + assert_equal "arr", pirate.catchphrase + end + private def with_partial_writes(klass, on = true) old = klass.partial_writes? -- cgit v1.2.3