From ad562c58eabfb8b44cb8ac9e87b87a7f998325fd Mon Sep 17 00:00:00 2001 From: Tom Lea Date: Mon, 11 Aug 2008 14:12:53 +0100 Subject: [PATCH] Dirty: treat two changes resulting in the original value as being unchanged. [#798 state:resolved] Signed-off-by: Jeremy Kemper --- activerecord/lib/active_record/dirty.rb | 5 +++- activerecord/test/cases/dirty_test.rb | 36 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb index 63bf8c8f5b..7e246e62ca 100644 --- a/activerecord/lib/active_record/dirty.rb +++ b/activerecord/lib/active_record/dirty.rb @@ -123,7 +123,10 @@ module ActiveRecord attr = attr.to_s # The attribute already has an unsaved change. - unless changed_attributes.include?(attr) + if changed_attributes.include?(attr) + old = changed_attributes[attr] + changed_attributes.delete(attr) unless field_changed?(attr, old, value) + else old = clone_attribute_value(:read_attribute, attr) changed_attributes[attr] = old if field_changed?(attr, old, value) end diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index feb47a15a8..4fe1d79f4d 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -191,6 +191,42 @@ class DirtyTest < ActiveRecord::TestCase assert !pirate.changed? end + def test_reverted_changes_are_not_dirty + phrase = "shiver me timbers" + pirate = Pirate.create!(:catchphrase => phrase) + pirate.catchphrase = "*hic*" + assert pirate.changed? + pirate.catchphrase = phrase + assert !pirate.changed? + end + + def test_reverted_changes_are_not_dirty_after_multiple_changes + phrase = "shiver me timbers" + pirate = Pirate.create!(:catchphrase => phrase) + 10.times do |i| + pirate.catchphrase = "*hic*" * i + assert pirate.changed? + end + assert pirate.changed? + pirate.catchphrase = phrase + assert !pirate.changed? + end + + + def test_reverted_changes_are_not_dirty_going_from_nil_to_value_and_back + pirate = Pirate.create!(:catchphrase => "Yar!") + + pirate.parrot_id = 1 + assert pirate.changed? + assert pirate.parrot_id_changed? + assert !pirate.catchphrase_changed? + + pirate.parrot_id = nil + assert !pirate.changed? + assert !pirate.parrot_id_changed? + assert !pirate.catchphrase_changed? + end + def test_save_should_store_serialized_attributes_even_with_partial_updates with_partial_updates(Topic) do topic = Topic.create!(:content => {:a => "a"})