From d0de53cbb2c2c4f8c3367e8fe4b984eabd8bfd56 Mon Sep 17 00:00:00 2001 From: Yohan Robert Date: Tue, 15 Nov 2016 14:35:58 +0100 Subject: [PATCH] Fix namespace lookup for collections and has_many (#1973) --- CHANGELOG.md | 1 + .../serializer/collection_serializer.rb | 4 +- .../namespace_lookup_test.rb | 56 ++++++++++++++++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10e7eb0b..8433c6ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Breaking changes: Fixes: +- [#1973](https://github.com/rails-api/active_model_serializers/pull/1973) Fix namespace lookup for collections and has_many relationships (@groyoh) - [#1887](https://github.com/rails-api/active_model_serializers/pull/1887) Make the comment reflect what the function does (@johnnymo87) - [#1890](https://github.com/rails-api/active_model_serializers/issues/1890) Ensure generator inherits from ApplicationSerializer when available (@richmolj) - [#1922](https://github.com/rails-api/active_model_serializers/pull/1922) Make railtie an optional dependency in runtime (@ggpasqualino) diff --git a/lib/active_model/serializer/collection_serializer.rb b/lib/active_model/serializer/collection_serializer.rb index 9b9b61d5..44b806a1 100644 --- a/lib/active_model/serializer/collection_serializer.rb +++ b/lib/active_model/serializer/collection_serializer.rb @@ -71,7 +71,9 @@ module ActiveModel end def serializer_from_resource(resource, serializer_context_class, options) - serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) } + serializer_class = options.fetch(:serializer) do + serializer_context_class.serializer_for(resource, namespace: options[:namespace]) + end if serializer_class.nil? ActiveModelSerializers.logger.debug "No serializer found for resource: #{resource.inspect}" diff --git a/test/action_controller/namespace_lookup_test.rb b/test/action_controller/namespace_lookup_test.rb index dfab02c4..ed5bb7ee 100644 --- a/test/action_controller/namespace_lookup_test.rb +++ b/test/action_controller/namespace_lookup_test.rb @@ -5,6 +5,7 @@ module ActionController class NamespaceLookupTest < ActionController::TestCase class Book < ::Model; end class Page < ::Model; end + class Chapter < ::Model; end class Writer < ::Model; end module Api @@ -19,6 +20,13 @@ module ActionController attributes :title, :body belongs_to :writer + has_many :chapters + end + + class ChapterSerializer < ActiveModel::Serializer + attribute :title do + "Chapter - #{object.title}" + end end class WriterSerializer < ActiveModel::Serializer @@ -32,7 +40,22 @@ module ActionController def implicit_namespaced_serializer writer = Writer.new(name: 'Bob') - book = Book.new(title: 'New Post', body: 'Body', writer: writer) + book = Book.new(title: 'New Post', body: 'Body', writer: writer, chapters: []) + + render json: book + end + + def implicit_namespaced_collection_serializer + chapter1 = Chapter.new(title: 'Oh') + chapter2 = Chapter.new(title: 'Oh my') + + render json: [chapter1, chapter2] + end + + def implicit_has_many_namespaced_serializer + chapter1 = Chapter.new(title: 'Odd World') + chapter2 = Chapter.new(title: 'New World') + book = Book.new(title: 'New Post', body: 'Body', chapters: [chapter1, chapter2]) render json: book end @@ -84,7 +107,36 @@ module ActionController assert_serializer Api::V3::BookSerializer - expected = { 'title' => 'New Post', 'body' => 'Body', 'writer' => { 'name' => 'Bob' } } + expected = { 'title' => 'New Post', 'body' => 'Body', 'writer' => { 'name' => 'Bob' }, 'chapters' => [] } + actual = JSON.parse(@response.body) + + assert_equal expected, actual + end + + test 'implicitly uses namespaced serializer for collection' do + get :implicit_namespaced_collection_serializer + + assert_serializer 'ActiveModel::Serializer::CollectionSerializer' + + expected = [{ 'title' => 'Chapter - Oh' }, { 'title' => 'Chapter - Oh my' }] + actual = JSON.parse(@response.body) + + assert_equal expected, actual + end + + test 'implicitly uses namespaced serializer for has_many' do + get :implicit_has_many_namespaced_serializer + + assert_serializer Api::V3::BookSerializer + + expected = { + 'title' => 'New Post', + 'body' => 'Body', 'writer' => nil, + 'chapters' => [ + { 'title' => 'Chapter - Odd World' }, + { 'title' => 'Chapter - New World' } + ] + } actual = JSON.parse(@response.body) assert_equal expected, actual