diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 4579fed0..d60a50a3 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -204,7 +204,9 @@ end association_serializer = build_serializer(association) # we must do this always because even if the current association is not # embeded in root, it might have its own associations that are embeded in root - hash.merge!(association_serializer.embedded_in_root_associations) {|key, oldval, newval| [newval, oldval].flatten } + hash.merge!(association_serializer.embedded_in_root_associations) do |key, oldval, newval| + oldval.merge(newval) { |_, oldval, newval| [oldval, newval].flatten.uniq } + end if association.embed_in_root? if association.embed_in_root_key? diff --git a/test/fixtures/active_record.rb b/test/fixtures/active_record.rb index ee69cc1b..c635a837 100644 --- a/test/fixtures/active_record.rb +++ b/test/fixtures/active_record.rb @@ -74,6 +74,10 @@ class ARSectionSerializer < ActiveModel::Serializer attributes 'name' end +class AREmbeddedSerializer < ActiveModel::Serializer + has_many :ar_tags, :ar_comments +end + ARPost.create(title: 'New post', body: 'A body!!!', ar_section: ARSection.create(name: 'ruby')).tap do |post| diff --git a/test/integration/active_record/active_record_test.rb b/test/integration/active_record/active_record_test.rb index 14ca1982..4989dc08 100644 --- a/test/integration/active_record/active_record_test.rb +++ b/test/integration/active_record/active_record_test.rb @@ -58,6 +58,22 @@ module ActiveModel end end + def test_serialization_embedding_ids_in_common_root_key + post_serializer = AREmbeddedSerializer.new(@post) + + embed(AREmbeddedSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do + embed(ARCommentSerializer, embed: :ids, embed_in_root: true, embed_in_root_key: :linked) do + assert_equal({ + 'ar_tags' => [{ name: 'short' }, + { name: 'whiny' }, + { name: 'happy' }], + 'ar_comments' => [{ body: 'what a dumb post', 'ar_tag_ids' => [3, 2] }, + { body: 'i liked it', 'ar_tag_ids' => [3, 1] }] + }, post_serializer.as_json[:linked]) + end + end + end + private def embed(serializer_class, options = {}) @@ -66,6 +82,7 @@ module ActiveModel serializer_class._associations.each_value do |association| association.embed = options[:embed] association.embed_in_root = options[:embed_in_root] + association.embed_in_root_key = options[:embed_in_root_key] end yield