Skip to content

Commit 987d3fb

Browse files
authored
Merge pull request rails#52797 from fatkodima/fix-nested-attributes-for-cpk
Fix updating nested attributes for models with composite primary keys
2 parents dfb2547 + 91e8acc commit 987d3fb

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

activerecord/lib/active_record/nested_attributes.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,12 +524,12 @@ def assign_nested_attributes_for_collection_association(association_name, attrib
524524
unless reject_new_record?(association_name, attributes)
525525
association.reader.build(attributes.except(*UNASSIGNABLE_KEYS))
526526
end
527-
elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes["id"].to_s }
527+
elsif existing_record = find_record_by_id(existing_records, attributes["id"])
528528
unless call_reject_if(association_name, attributes)
529529
# Make sure we are operating on the actual object which is in the association's
530530
# proxy_target array (either by finding it, or adding it if not found)
531531
# Take into account that the proxy_target may have changed due to callbacks
532-
target_record = association.target.detect { |record| record.id.to_s == attributes["id"].to_s }
532+
target_record = find_record_by_id(association.target, attributes["id"])
533533
if target_record
534534
existing_record = target_record
535535
else
@@ -620,5 +620,16 @@ def raise_nested_attributes_record_not_found!(association_name, record_id)
620620
raise RecordNotFound.new("Couldn't find #{model} with ID=#{record_id} for #{self.class.name} with ID=#{id}",
621621
model, "id", record_id)
622622
end
623+
624+
def find_record_by_id(records, id)
625+
return if records.empty?
626+
627+
if records.first.class.composite_primary_key?
628+
id = Array(id).map(&:to_s)
629+
records.find { |record| Array(record.id).map(&:to_s) == id }
630+
else
631+
records.find { |record| record.id.to_s == id.to_s }
632+
end
633+
end
623634
end
624635
end

activerecord/test/cases/nested_attributes_test.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
require "models/pet"
1515
require "models/entry"
1616
require "models/message"
17+
require "models/cpk"
1718
require "active_support/hash_with_indifferent_access"
1819

1920
class TestNestedAttributesInGeneral < ActiveRecord::TestCase
@@ -232,6 +233,15 @@ def test_should_not_create_duplicates_with_create_with
232233
)
233234
end
234235
end
236+
237+
def test_updating_models_with_cpk_provided_as_strings
238+
book = Cpk::Book.create!(id: [1, 2], shop_id: 3)
239+
book.chapters.create!(id: [1, 3], title: "Title")
240+
241+
book.update!(chapters_attributes: { id: ["1", "3"], title: "New title" })
242+
assert_equal 1, book.reload.chapters.count
243+
assert_equal "New title", book.chapters.first.title
244+
end
235245
end
236246

237247
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase

activerecord/test/models/cpk/book.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class Book < ActiveRecord::Base
1010
belongs_to :author, class_name: "Cpk::Author"
1111

1212
has_many :chapters, foreign_key: [:author_id, :book_id]
13+
accepts_nested_attributes_for :chapters
1314

1415
before_destroy :prevent_destroy_if_set
1516

0 commit comments

Comments
 (0)