From 99677c0c5868b3ea26cfae6332648cbb27b7ff1f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 4 Nov 2013 10:48:17 -0200 Subject: [PATCH] Pass scope through to associations via @lastobelus Closes #433 --- lib/active_model/serializer.rb | 2 +- lib/active_model/serializer/associations.rb | 33 +++++++++++++------ .../active_model/serializer/scope_test.rb | 28 ++++++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 6d254ff0..b0563bee 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -156,7 +156,7 @@ end end def serialize(association, object) - association.build_serializer(object).serializable_object + association.build_serializer(object, scope: scope).serializable_object end def serialize_ids(association) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 3858650b..76574dd7 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -34,6 +34,17 @@ module ActiveModel @embed_objects = embed == :object || embed == :objects end + def build_serializer(object, options = {}) + @serializer_class.new(object, options.merge(@options)) + end + + private + + def use_array_serializer! + @options.merge!(each_serializer: @serializer_class) + @serializer_class = ArraySerializer + end + class HasOne < Association def initialize(name, *args) super @@ -41,13 +52,14 @@ module ActiveModel @key ||= "#{name}_id" end - def build_serializer(object) + def build_serializer(object, options = {}) if object.respond_to?(:to_ary) - @options.merge!(each_serializer: @serializer_class) - @serializer_class = ArraySerializer + use_array_serializer! + else + @serializer_class ||= Serializer.serializer_for(object) || DefaultSerializer end - @serializer_class ||= Serializer.serializer_for(object) || DefaultSerializer - @serializer_class.new(object, @options) + + super end end @@ -58,13 +70,14 @@ module ActiveModel @key ||= "#{name.to_s.singularize}_ids" end - def build_serializer(object) + def build_serializer(object, options = {}) if @serializer_class && !(@serializer_class <= ArraySerializer) - @options.merge!(each_serializer: @serializer_class) - @serializer_class = ArraySerializer + use_array_serializer! + else + @serializer_class ||= ArraySerializer end - @serializer_class ||= ArraySerializer - @serializer_class.new(object, @options) + + super end end end diff --git a/test/unit/active_model/serializer/scope_test.rb b/test/unit/active_model/serializer/scope_test.rb index 78c1b8d7..dea6c114 100644 --- a/test/unit/active_model/serializer/scope_test.rb +++ b/test/unit/active_model/serializer/scope_test.rb @@ -17,5 +17,33 @@ module ActiveModel 'user' end end + + class NestedScopeTest < ActiveModel::TestCase + def setup + @association = UserSerializer._associations[:profile] + @old_association = @association.dup + @user = User.new({ name: 'Name 1', email: 'mail@server.com', gender: 'M' }) + @user_serializer = UserSerializer.new(@user, scope: 'user') + end + + def teardown + UserSerializer._associations[:profile] = @old_association + end + + def test_scope_passed_through + @association.serializer_class = Class.new(ActiveModel::Serializer) do + def name + scope + end + + attributes :name + end + + assert_equal({ + name: 'Name 1', email: 'mail@server.com', profile: { name: 'user' } + }, @user_serializer.serializable_hash) + end + end + end end