Skip to content
This repository
Browse code

AR::Base#clone fixed to set dirty bits for cloned object

[#2919 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information...
commit 4db10bce7b5ca794c4d408de3b8002bf58233bb7 1 parent e1a340a
Dmitry Lipovoi authored May 17, 2010 jeremy committed May 16, 2010
8  activerecord/lib/active_record/base.rb
@@ -1463,12 +1463,18 @@ def initialize_copy(other)
1463 1463
         callback(:after_initialize) if respond_to_without_attributes?(:after_initialize)
1464 1464
         cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
1465 1465
         cloned_attributes.delete(self.class.primary_key)
  1466
+
1466 1467
         @attributes = cloned_attributes
  1468
+
  1469
+        @changed_attributes = {}
  1470
+        attributes_from_column_definition.each do |attr, orig_value|
  1471
+          @changed_attributes[attr] = orig_value if field_changed?(attr, orig_value, @attributes[attr])
  1472
+        end
  1473
+
1467 1474
         clear_aggregation_cache
1468 1475
         @attributes_cache = {}
1469 1476
         @new_record = true
1470 1477
         ensure_proper_type
1471  
-        @changed_attributes = other.changed_attributes.dup
1472 1478
 
1473 1479
         if scope = self.class.send(:current_scoped_methods)
1474 1480
           create_with = scope.scope_for_create
50  activerecord/test/cases/base_test.rb
@@ -1456,6 +1456,56 @@ def test_clone_preserves_subtype
1456 1456
     assert_kind_of Client, clone
1457 1457
   end
1458 1458
 
  1459
+  def test_clone_of_new_object_with_defaults
  1460
+    developer = Developer.new
  1461
+    assert !developer.name_changed?
  1462
+    assert !developer.salary_changed?
  1463
+
  1464
+    cloned_developer = developer.clone
  1465
+    assert !cloned_developer.name_changed?
  1466
+    assert !cloned_developer.salary_changed?
  1467
+  end
  1468
+
  1469
+  def test_clone_of_new_object_marks_attributes_as_dirty
  1470
+    developer = Developer.new :name => 'Bjorn', :salary => 100000
  1471
+    assert developer.name_changed?
  1472
+    assert developer.salary_changed?
  1473
+
  1474
+    cloned_developer = developer.clone
  1475
+    assert cloned_developer.name_changed?
  1476
+    assert cloned_developer.salary_changed?
  1477
+  end
  1478
+
  1479
+  def test_clone_of_new_object_marks_as_dirty_only_changed_attributes
  1480
+    developer = Developer.new :name => 'Bjorn'
  1481
+    assert developer.name_changed?            # obviously
  1482
+    assert !developer.salary_changed?         # attribute has non-nil default value, so treated as not changed
  1483
+
  1484
+    cloned_developer = developer.clone
  1485
+    assert cloned_developer.name_changed?
  1486
+    assert !cloned_developer.salary_changed?  # ... and cloned instance should behave same
  1487
+  end
  1488
+
  1489
+  def test_clone_of_saved_object_marks_attributes_as_dirty
  1490
+    developer = Developer.create! :name => 'Bjorn', :salary => 100000
  1491
+    assert !developer.name_changed?
  1492
+    assert !developer.salary_changed?
  1493
+
  1494
+    cloned_developer = developer.clone
  1495
+    assert cloned_developer.name_changed?     # both attributes differ from defaults
  1496
+    assert cloned_developer.salary_changed?
  1497
+  end
  1498
+
  1499
+  def test_clone_of_saved_object_marks_as_dirty_only_changed_attributes
  1500
+    developer = Developer.create! :name => 'Bjorn'
  1501
+    assert !developer.name_changed?           # both attributes of saved object should be threated as not changed
  1502
+    assert !developer.salary_changed?
  1503
+
  1504
+    cloned_developer = developer.clone
  1505
+    assert cloned_developer.name_changed?     # ... but on cloned object should be
  1506
+    assert !cloned_developer.salary_changed?  # ... BUT salary has non-nil default which should be threated as not changed on cloned instance
  1507
+  end
  1508
+
1459 1509
   def test_bignum
1460 1510
     company = Company.find(1)
1461 1511
     company.rating = 2147483647

0 notes on commit 4db10bc

Please sign in to comment.
Something went wrong with that request. Please try again.