From 0057d2df71ec7c2a788acd3b4bade263fc0fe361 Mon Sep 17 00:00:00 2001 From: Szetobo Date: Mon, 12 Jul 2010 09:47:47 +0800 Subject: [PATCH] association load target shouldn't replace records from db if it is already loaded by nested attributes assignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#5053 state:resolved] Signed-off-by: José Valim --- .../associations/association_collection.rb | 7 ++++--- activerecord/test/cases/nested_attributes_test.rb | 14 +++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 7100be0245..692badcc5c 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -396,11 +396,12 @@ def load_target if @target.is_a?(Array) && @target.any? @target = find_target.map do |f| i = @target.index(f) - t = @target.delete_at(i) if i - if t && t.changed? + if i + t = @target.delete_at(i) + keys = ["id"] + t.changes.keys + (f.attribute_names - t.attribute_names) + t.attributes = f.attributes.except(*keys) t else - f.mark_for_destruction if t && t.marked_for_destruction? f end end + @target diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 20bd4f6a76..df09bbd46a 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -862,7 +862,19 @@ def setup assert_equal 1, @ship.parts.proxy_target.size assert_equal 'Deck', @ship.parts[0].name end - + + test "if association is not loaded and child doesn't change and I am saving a grandchild then in memory record should be used" do + @ship.parts_attributes=[{:id => @part.id,:trinkets_attributes =>[{:id => @trinket.id, :name => 'Ruby'}]}] + assert_equal 1, @ship.parts.proxy_target.size + assert_equal 'Mast', @ship.parts[0].name + assert_no_difference("@ship.parts[0].trinkets.proxy_target.size") do + @ship.parts[0].trinkets.proxy_target.size + end + assert_equal 'Ruby', @ship.parts[0].trinkets[0].name + @ship.save + assert_equal 'Ruby', @ship.parts[0].trinkets[0].name + end + test "when grandchild changed in memory, saving parent should save grandchild" do @trinket.name = "changed" @ship.save -- GitLab