From 1bb0605dfe09f654d9ad43a86b69183cd6f653f2 Mon Sep 17 00:00:00 2001 From: Mike Mangino Date: Fri, 3 Mar 2017 15:02:35 -0500 Subject: Don't accidentally lose includes in serialization --- activemodel/CHANGELOG.md | 3 +++ activemodel/lib/active_model/serialization.rb | 2 +- activemodel/test/cases/serialization_test.rb | 12 +++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'activemodel') diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 1503b6a3e4..ba5ba825b3 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,3 +1,6 @@ +* Don't only take the first hash key in serialization :includes. Doing so silently loses options in `includes: [:account, {address: {only: id}, user: {only: id}]` + + *Mike Mangino* ## Rails 5.1.0.beta1 (February 23, 2017) ## * Remove deprecated behavior that halts callbacks when the return is false. diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb index 77834f26fc..78e46c49eb 100644 --- a/activemodel/lib/active_model/serialization.rb +++ b/activemodel/lib/active_model/serialization.rb @@ -177,7 +177,7 @@ module ActiveModel return unless includes = options[:include] unless includes.is_a?(Hash) - includes = Hash[Array(includes).map { |n| n.is_a?(Hash) ? n.to_a.first : [n, {}] }] + includes = Hash[Array(includes).flat_map { |n| n.is_a?(Hash) ? n.to_a : [[n, {}]] }] end includes.each do |association, opts| diff --git a/activemodel/test/cases/serialization_test.rb b/activemodel/test/cases/serialization_test.rb index f78efd2f0c..3446742d8c 100644 --- a/activemodel/test/cases/serialization_test.rb +++ b/activemodel/test/cases/serialization_test.rb @@ -144,6 +144,12 @@ class SerializationTest < ActiveModel::TestCase assert_equal expected, @user.serializable_hash(include: { address: { only: "street" } }) end + def test_multiple_includes_with_options + expected = { "email" => "david@example.com", "gender" => "male", "name" => "David", + "address" => { "street" => "123 Lane" } } + assert_equal expected, @user.serializable_hash(include: { address: { only: "street" } }) + end + def test_nested_include @user.friends.first.friends = [@user] expected = { "email" => "david@example.com", "gender" => "male", "name" => "David", @@ -168,8 +174,8 @@ class SerializationTest < ActiveModel::TestCase def test_multiple_includes_with_options expected = { "email" => "david@example.com", "gender" => "male", "name" => "David", "address" => { "street" => "123 Lane" }, - "friends" => [{ "name" => "Joe", "email" => "joe@example.com", "gender" => "male" }, - { "name" => "Sue", "email" => "sue@example.com", "gender" => "female" }] } - assert_equal expected, @user.serializable_hash(include: [{ address: { only: "street" } }, :friends]) + "friends" => [{ "name" => "Joe" }, + { "name" => "Sue" }] } + assert_equal expected, @user.serializable_hash(include: [ address: { only: "street" } , friends: {only: "name"}]) end end -- cgit v1.2.3