From a9fc59e9f58bf11d496fec030b7d5a7043f725d6 Mon Sep 17 00:00:00 2001 From: eugenebolshakov Date: Sun, 16 May 2010 20:11:26 +0400 Subject: [PATCH] clones should be marked as dirty --- activerecord/lib/active_record/base.rb | 13 +++++++++++++ activerecord/test/cases/dirty_test.rb | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 0 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 04c474c..ccadddf 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1459,10 +1459,23 @@ module ActiveRecord #:nodoc: # of test@test.com. However the test_clone test method seems to test that this is not the case. As a result the # after_initialize callback has to be run *before* the copying of the atrributes rather than afterwards in order # for all tests to pass. This makes no sense to me. + # callback(:after_initialize) if respond_to_without_attributes?(:after_initialize) cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast) cloned_attributes.delete(self.class.primary_key) + @attributes = cloned_attributes + + clean_state = self.class.new + clean_state_attributes = clean_state.attributes + clean_state_attributes.delete(self.class.primary_key) + + clean_state_attributes.each do |key, value| + if clean_state.send(:field_changed?, key, value, @attributes[key]) + send("#{key}_will_change!") + end + end + clear_aggregation_cache @attributes_cache = {} @new_record = true diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index 7a17ef1..f96cfea 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -338,6 +338,20 @@ class DirtyTest < ActiveRecord::TestCase assert !pirate.changed? end + def test_cloned_object_should_threat_as_changed_non_default_attribute_values + topic = Topic.new + topic_cloned = topic.clone + assert_equal true, topic_cloned.approved + assert !topic_cloned.approved_changed? + end + + def test_cloned_models_should_be_dirty + phrase = "shiver me timbers" + pirate = Pirate.create!(:catchphrase => phrase) + pirate_cloned = pirate.clone + assert pirate_cloned.changed? + end + def test_reverted_changes_are_not_dirty phrase = "shiver me timbers" pirate = Pirate.create!(:catchphrase => phrase) -- 1.6.3.3