From 90343cea4dcdd84abd1a86cf3175e26bd0b7ca81 Mon Sep 17 00:00:00 2001 From: Andrey Chernih Date: Thu, 25 Sep 2014 16:59:47 +0400 Subject: [PATCH] Make sure `render json: ..., each_serializer: ...` is working with Enumerables If you try to render Enumerable with custom `each_serializer` then it will render with default serializer instead: ```ruby render json: sequel_scope, each_serializer: CustomSerializer ``` This commit fixes this behaviour. Most likely fixes https://github.com/rails-api/active_model_serializers/issues/664 as well --- lib/action_controller/serialization.rb | 2 +- lib/active_model/serializer.rb | 2 +- test/fixtures/poro.rb | 4 ++++ .../action_controller/serialization_test.rb | 16 ++++++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb index d86b2ac0..5b2a3d35 100644 --- a/lib/action_controller/serialization.rb +++ b/lib/action_controller/serialization.rb @@ -84,7 +84,7 @@ module ActionController if serializer = options.fetch(:serializer, default_serializer(resource)) options[:scope] = serialization_scope unless options.has_key?(:scope) - if resource.respond_to?(:to_ary) + if resource.respond_to?(:each) options[:resource_name] = controller_name options[:namespace] = namespace_for_serializer if namespace_for_serializer end diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index e8f52e57..8281b495 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -56,7 +56,7 @@ end attr_reader :key_format def serializer_for(resource, options = {}) - if resource.respond_to?(:to_ary) + if resource.respond_to?(:each) if Object.constants.include?(:ArraySerializer) ::ArraySerializer else diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index 14fa3e5a..8b4f6c35 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -92,6 +92,10 @@ class ProfileSerializer < ActiveModel::Serializer attributes :name, :description end +class DifferentProfileSerializer < ActiveModel::Serializer + attributes :name +end + class CategorySerializer < ActiveModel::Serializer attributes :name diff --git a/test/integration/action_controller/serialization_test.rb b/test/integration/action_controller/serialization_test.rb index 5d173606..f161de64 100644 --- a/test/integration/action_controller/serialization_test.rb +++ b/test/integration/action_controller/serialization_test.rb @@ -283,5 +283,21 @@ module ActionController assert_equal("{\"my\":[{\"name\":\"Name 1\",\"email\":\"mail@server.com\",\"profile_id\":#{@controller.user.profile.object_id}}],\"profiles\":[{\"name\":\"N1\",\"description\":\"D1\"}]}", @response.body) end end + + class ExplicitEachSerializerWithEnumarableObjectTest < ActionController::TestCase + class MyController < ActionController::Base + def render_array + render json: [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })].to_enum, each_serializer: DifferentProfileSerializer + end + end + + tests MyController + + def test_render_array + get :render_array + assert_equal 'application/json', @response.content_type + assert_equal '{"my":[{"name":"Name 1"}]}', @response.body + end + end end end