diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb index c966c9f1..69573298 100644 --- a/lib/action_controller/serialization.rb +++ b/lib/action_controller/serialization.rb @@ -65,11 +65,21 @@ module ActionController options = default_serializer_options.merge(options) if serializer = options.fetch(:serializer, ActiveModel::Serializer.serializer_for(resource)) - options[:scope] = serialization_scope unless options.has_key?(:scope) + options[:context] = build_context_from options[:context] options[:resource_name] = controller_name if resource.respond_to?(:to_ary) serializer.new(resource, options) end end + + def build_context_from(context_option) + default_context.tap do |context| + context.merge! context_option if context_option + end + end + + def default_context + { scope: serialization_scope } + end end end diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index dfb86844..9e454888 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -14,14 +14,14 @@ module ActiveModel def initialize(object, options={}) @object = object - @scope = options[:scope] + @context = options[:context] || {} @root = options.fetch(:root, self.class._root) @meta_key = options[:meta_key] || :meta @meta = options[@meta_key] @each_serializer = options[:each_serializer] @resource_name = options[:resource_name] end - attr_accessor :object, :scope, :root, :meta_key, :meta + attr_accessor :object, :context, :root, :meta_key, :meta def json_key if root.nil? @@ -33,7 +33,7 @@ module ActiveModel def serializer_for(item) serializer_class = @each_serializer || Serializer.serializer_for(item) || DefaultSerializer - serializer_class.new(item, scope: scope) + serializer_class.new(item, context: context) end def serializable_object diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index fba7fffa..b7242452 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -103,13 +103,13 @@ end def initialize(object, options={}) @object = object - @scope = options[:scope] + @context = options[:context] || {} @root = options.fetch(:root, self.class._root) @meta_key = options[:meta_key] || :meta @meta = options[@meta_key] @wrap_in_array = options[:_wrap_in_array] end - attr_accessor :object, :scope, :root, :meta_key, :meta + attr_accessor :object, :context, :root, :meta_key, :meta def json_key if root == true || root.nil? @@ -166,7 +166,7 @@ end def build_serializer(association) object = send(association.name) - association.build_serializer(object, scope: scope) + association.build_serializer(object, context: context) end def serialize(association) diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index a43954b5..fb5fcec2 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -47,7 +47,7 @@ end class ProfileSerializer < ActiveModel::Serializer def description description = object.read_attribute_for_serialization(:description) - scope ? "#{description} - #{scope}" : description + context[:scope] ? "#{description} - #{context[:scope]}" : description end attributes :name, :description diff --git a/test/integration/action_controller/serialization_test.rb b/test/integration/action_controller/serialization_test.rb index 7ffd4c56..f42bb803 100644 --- a/test/integration/action_controller/serialization_test.rb +++ b/test/integration/action_controller/serialization_test.rb @@ -43,7 +43,7 @@ module ActionController class DefaultOptionsForSerializerScopeTest < ActionController::TestCase class MyController < ActionController::Base def default_serializer_options - { scope: current_admin } + { context: { scope: current_admin } } end def render_using_scope_set_in_default_serializer_options @@ -73,7 +73,7 @@ module ActionController class ExplicitSerializerScopeTest < ActionController::TestCase class MyController < ActionController::Base def render_using_implicit_serializer_and_explicit_scope - render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }), scope: current_admin + render json: Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }), context: { scope: current_admin } end private diff --git a/test/unit/active_model/array_serializer/context_test.rb b/test/unit/active_model/array_serializer/context_test.rb new file mode 100644 index 00000000..e63741c6 --- /dev/null +++ b/test/unit/active_model/array_serializer/context_test.rb @@ -0,0 +1,38 @@ +require 'test_helper' + +module ActiveModel + class ArraySerializer + class ContextTest < ActiveModel::TestCase + def test_context_using_a_hash + serializer = ArraySerializer.new(nil, context: { a: 1, b: 2 }) + assert_equal(1, serializer.context[:a]) + assert_equal(2, serializer.context[:b]) + end + + def test_context_using_an_object + serializer = ArraySerializer.new(nil, context: Struct.new(:a, :b).new(1, 2)) + assert_equal(1, serializer.context.a) + assert_equal(2, serializer.context.b) + end + end + + class ScopeTest < ActiveModel::TestCase + def test_array_serializer_pass_context_to_item_serializers + array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }), + Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })] + serializer = ArraySerializer.new(array, context: { scope: current_user }) + + expected = [{ name: 'Name 1', description: 'Description 1 - user' }, + { name: 'Name 2', description: 'Description 2 - user' }] + + assert_equal expected, serializer.serializable_array + end + + private + + def current_user + 'user' + end + end + end +end diff --git a/test/unit/active_model/array_serializer/scope_test.rb b/test/unit/active_model/array_serializer/scope_test.rb deleted file mode 100644 index b9c6034f..00000000 --- a/test/unit/active_model/array_serializer/scope_test.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'test_helper' - -module ActiveModel - class ArraySerializer - class ScopeTest < ActiveModel::TestCase - def test_array_serializer_pass_options_to_items_serializers - array = [Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }), - Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' })] - serializer = ArraySerializer.new(array, scope: current_user) - - expected = [{ name: 'Name 1', description: 'Description 1 - user' }, - { name: 'Name 2', description: 'Description 2 - user' }] - - assert_equal expected, serializer.serializable_array - end - - private - - def current_user - 'user' - end - end - end -end diff --git a/test/unit/active_model/serializer/scope_test.rb b/test/unit/active_model/serializer/context_test.rb similarity index 50% rename from test/unit/active_model/serializer/scope_test.rb rename to test/unit/active_model/serializer/context_test.rb index dea6c114..060769d0 100644 --- a/test/unit/active_model/serializer/scope_test.rb +++ b/test/unit/active_model/serializer/context_test.rb @@ -2,48 +2,45 @@ require 'test_helper' module ActiveModel class Serializer - class ScopeTest < ActiveModel::TestCase - def setup - @serializer = ProfileSerializer.new(nil, scope: current_user) + class ContextTest < ActiveModel::TestCase + def test_context_using_a_hash + serializer = UserSerializer.new(nil, context: { a: 1, b: 2 }) + assert_equal(1, serializer.context[:a]) + assert_equal(2, serializer.context[:b]) end - def test_scope - assert_equal('user', @serializer.scope) - end - - private - - def current_user - 'user' + def test_context_using_an_object + serializer = UserSerializer.new(nil, context: Struct.new(:a, :b).new(1, 2)) + assert_equal(1, serializer.context.a) + assert_equal(2, serializer.context.b) end end - class NestedScopeTest < ActiveModel::TestCase + class ContextAssociationTest < 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') + @user_serializer = UserSerializer.new(@user, context: { admin: true }) end def teardown UserSerializer._associations[:profile] = @old_association end - def test_scope_passed_through + def test_context_passed_through @association.serializer_class = Class.new(ActiveModel::Serializer) do def name - scope + context[:admin] ? 'Admin' : 'User' end attributes :name end assert_equal({ - name: 'Name 1', email: 'mail@server.com', profile: { name: 'user' } + name: 'Name 1', email: 'mail@server.com', profile: { name: 'Admin' } }, @user_serializer.serializable_hash) end end - end end