From 1e5ea0b35669a0a0ce3e7118998d4344ced45e83 Mon Sep 17 00:00:00 2001 From: Adrian Mugnolo and Santiago Pastorino Date: Mon, 13 Jan 2014 16:48:38 -0200 Subject: [PATCH] Move options to configuration --- lib/active_model/array_serializer.rb | 37 +++++++++++-------- lib/active_model/default_serializer.rb | 7 ++-- lib/active_model/serializer.rb | 29 ++++++++------- lib/active_model/serializer/associations.rb | 5 ++- lib/active_model/serializer/configuration.rb | 28 +++++++++++--- lib/active_model/serializer/dsl.rb | 4 ++ .../array_serializer/meta_test.rb | 6 +-- .../array_serializer/root_test.rb | 12 +++--- .../unit/active_model/serializer/root_test.rb | 22 +++++------ 9 files changed, 90 insertions(+), 60 deletions(-) diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index 32a382f0..4d8b2ca1 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -7,44 +7,49 @@ module ActiveModel include Serializable class << self - attr_accessor :_root - alias root _root= - alias root= _root= + def configuration + @configuration ||= + if self == ArraySerializer + Serializer::Configuration.global + else + superclass.configuration.build + end + end end - def initialize(object, options={}) - @object = object - @scope = options[:scope] - @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] + extend Forwardable + + def_delegators :configuration, :scope, :root, :meta_key, :meta, :each_serializer, :resource_name + + attr_accessor :object, :configuration + + def initialize(object, options = {}) + @object = object + @configuration = self.class.configuration.build options end - attr_accessor :object, :scope, :root, :meta_key, :meta def json_key if root.nil? - @resource_name + resource_name else root end end def serializer_for(item) - serializer_class = @each_serializer || Serializer.serializer_for(item) || DefaultSerializer + serializer_class = each_serializer || Serializer.serializer_for(item) || DefaultSerializer serializer_class.new(item, scope: scope) end def serializable_object - @object.map do |item| + object.map do |item| serializer_for(item).serializable_object end end alias_method :serializable_array, :serializable_object def embedded_in_root_associations - @object.each_with_object({}) do |item, hash| + object.each_with_object({}) do |item, hash| serializer_for(item).embedded_in_root_associations.each_pair do |type, objects| next if !objects || objects.flatten.empty? diff --git a/lib/active_model/default_serializer.rb b/lib/active_model/default_serializer.rb index 270ef061..d3a00ac2 100644 --- a/lib/active_model/default_serializer.rb +++ b/lib/active_model/default_serializer.rb @@ -7,13 +7,14 @@ module ActiveModel class DefaultSerializer include ActiveModel::Serializable - attr_reader :object + attr_reader :object, :configuration - def initialize(object, options=nil) + def initialize(object, options = nil) @object = object + @configuration = Serializer::Configuration::Null.instance end - def as_json(options={}) + def as_json(options = {}) @object.as_json end alias serializable_hash as_json diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index b8a1b5fa..2005b433 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -12,7 +12,6 @@ module ActiveModel class << self def inherited(base) - base._root = _root base._attributes = (_attributes || []).dup base._associations = (_associations || {}).dup end @@ -39,9 +38,7 @@ module ActiveModel end end - attr_accessor :_root, :_attributes, :_associations - alias root _root= - alias root= _root= + attr_accessor :_attributes, :_associations def root_name name.demodulize.underscore.sub(/_serializer$/, '') if name @@ -49,10 +46,15 @@ module ActiveModel extend Forwardable - def_delegators :dsl, :attributes, :has_one, :has_many, :embed + def_delegators :dsl, :attributes, :has_one, :has_many, :embed, :root def configuration - @configuration ||= Configuration.global.build + @configuration ||= + if self == Serializer + Configuration.global + else + superclass.configuration.build + end end private @@ -62,15 +64,14 @@ module ActiveModel end end - attr_accessor :object, :scope, :root, :meta_key, :meta, :configuration + extend Forwardable - def initialize(object, options={}) + def_delegators :configuration, :scope, :root, :meta_key, :meta, :wrap_in_array + + attr_accessor :object, :configuration + + def initialize(object, options = {}) @object = object - @scope = options[:scope] - @root = options.fetch(:root, self.class._root) - @meta_key = options[:meta_key] || :meta - @meta = options[@meta_key] - @wrap_in_array = options[:_wrap_in_array] @configuration = self.class.configuration.build options end @@ -149,7 +150,7 @@ module ActiveModel return nil if object.nil? hash = attributes hash.merge! associations - @wrap_in_array ? [hash] : hash + wrap_in_array ? [hash] : hash end alias_method :serializable_hash, :serializable_object end diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index e69a6da9..a8306b80 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -58,8 +58,9 @@ module ActiveModel end def build_serializer(object, options = {}) - options[:_wrap_in_array] = embed_in_root? - super + super.tap do |instance| + instance.configuration.wrap_in_array = embed_in_root? + end end end diff --git a/lib/active_model/serializer/configuration.rb b/lib/active_model/serializer/configuration.rb index 855e0876..f581cb9b 100644 --- a/lib/active_model/serializer/configuration.rb +++ b/lib/active_model/serializer/configuration.rb @@ -23,7 +23,7 @@ module ActiveModel end def default_options - { embed: :objects } + { embed: :objects, meta_key: :meta } end end @@ -31,11 +31,21 @@ module ActiveModel self.class.new options, self end + attr_reader :scope, :each_serializer, :resource_name + attr_writer :root, :meta, :meta_key + attr_accessor :wrap_in_array + def initialize(options = {}, parent = Null.instance) - @root = read_option options, :root - @embed = read_option options, :embed - @embed_in_root = read_option options, :embed_in_root - @parent = parent + @parent = parent + @root = read_option options, :root + @embed = read_option options, :embed + @embed_in_root = read_option options, :embed_in_root + @scope = options[:scope] + @meta_key = read_option options, :meta_key + @meta = read_option options, meta_key + @wrap_in_array = options[:_wrap_in_array] + @each_serializer = options[:each_serializer] + @resource_name = options[:resource_name] end def root @@ -50,6 +60,14 @@ module ActiveModel return_first @embed_in_root, parent.embed_in_root end + def meta_key + return_first @meta_key, parent.meta_key + end + + def meta + return_first @meta, parent.meta + end + # FIXME: Get rid of this mess. def embed_objects=(value) @embed = :objects if value diff --git a/lib/active_model/serializer/dsl.rb b/lib/active_model/serializer/dsl.rb index 02b0fa96..a28d4b7d 100644 --- a/lib/active_model/serializer/dsl.rb +++ b/lib/active_model/serializer/dsl.rb @@ -30,6 +30,10 @@ module ActiveModel configuration.embed_in_root = true if options[:embed_in_root] || options[:include] end + def root(value) + configuration.root = value + end + extend Forwardable def_delegators :serializer_class, :configuration diff --git a/test/unit/active_model/array_serializer/meta_test.rb b/test/unit/active_model/array_serializer/meta_test.rb index 29b0cd7d..e1220346 100644 --- a/test/unit/active_model/array_serializer/meta_test.rb +++ b/test/unit/active_model/array_serializer/meta_test.rb @@ -11,7 +11,7 @@ module ActiveModel end def test_meta - @serializer.meta = { total: 10 } + @serializer.configuration.meta = { total: 10 } assert_equal({ 'profiles' => [ @@ -30,8 +30,8 @@ module ActiveModel end def test_meta_using_meta_key - @serializer.meta_key = :my_meta - @serializer.meta = { total: 10 } + @serializer.configuration.meta_key = :my_meta + @serializer.configuration.meta = { total: 10 } assert_equal({ 'profiles' => [ diff --git a/test/unit/active_model/array_serializer/root_test.rb b/test/unit/active_model/array_serializer/root_test.rb index 6cade47a..5c50bf99 100644 --- a/test/unit/active_model/array_serializer/root_test.rb +++ b/test/unit/active_model/array_serializer/root_test.rb @@ -4,14 +4,14 @@ module ActiveModel class ArraySerializer class RootAsOptionTest < Minitest::Test def setup - @old_root = ArraySerializer._root + @old_root = ArraySerializer.configuration.root @profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }) @profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' }) @serializer = ArraySerializer.new([@profile1, @profile2], root: :initialize) end def teardown - ArraySerializer._root = @old_root + ArraySerializer.configuration.root = @old_root end def test_root_is_not_displayed_using_serializable_array @@ -40,7 +40,7 @@ module ActiveModel end def test_using_false_root_in_initialize_takes_precedence - ArraySerializer._root = 'root' + ArraySerializer.configuration.root = 'root' @serializer = ArraySerializer.new([@profile1, @profile2], root: false) assert_equal([ @@ -52,8 +52,8 @@ module ActiveModel class RootInSerializerTest < Minitest::Test def setup - @old_root = ArraySerializer._root - ArraySerializer._root = :in_serializer + @old_root = ArraySerializer.configuration.root + ArraySerializer.configuration.root = :in_serializer @profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }) @profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' }) @serializer = ArraySerializer.new([@profile1, @profile2]) @@ -61,7 +61,7 @@ module ActiveModel end def teardown - ArraySerializer._root = @old_root + ArraySerializer.configuration.root = @old_root end def test_root_is_not_displayed_using_serializable_hash diff --git a/test/unit/active_model/serializer/root_test.rb b/test/unit/active_model/serializer/root_test.rb index 868e1417..3fdcb14f 100644 --- a/test/unit/active_model/serializer/root_test.rb +++ b/test/unit/active_model/serializer/root_test.rb @@ -4,14 +4,14 @@ module ActiveModel class Serializer class RootAsOptionTest < Minitest::Test def setup - @old_root = ProfileSerializer._root + @old_root = ProfileSerializer.configuration.root @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }) @serializer = ProfileSerializer.new(@profile, root: :initialize) - ProfileSerializer._root = true + ProfileSerializer.root true end def teardown - ProfileSerializer._root = @old_root + ProfileSerializer.root @old_root end def test_root_is_not_displayed_using_serializable_hash @@ -47,7 +47,7 @@ module ActiveModel end def test_using_false_root_in_initializer_takes_precedence - ProfileSerializer._root = 'root' + ProfileSerializer.root 'root' @serializer = ProfileSerializer.new(@profile, root: false) assert_equal({ @@ -56,31 +56,31 @@ module ActiveModel end def test_root_inheritance - ProfileSerializer._root = 'profile' + ProfileSerializer.root 'profile' inherited_serializer_klass = Class.new(ProfileSerializer) - inherited_serializer_klass._root = 'inherited_profile' + inherited_serializer_klass.root 'inherited_profile' another_inherited_serializer_klass = Class.new(ProfileSerializer) assert_equal('inherited_profile', - inherited_serializer_klass._root) + inherited_serializer_klass.configuration.root) assert_equal('profile', - another_inherited_serializer_klass._root) + another_inherited_serializer_klass.configuration.root) end end class RootInSerializerTest < Minitest::Test def setup - @old_root = ProfileSerializer._root - ProfileSerializer._root = :in_serializer + @old_root = ProfileSerializer.configuration.root + ProfileSerializer.root :in_serializer profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }) @serializer = ProfileSerializer.new(profile) @rooted_serializer = ProfileSerializer.new(profile, root: :initialize) end def teardown - ProfileSerializer._root = @old_root + ProfileSerializer.root @old_root end def test_root_is_not_displayed_using_serializable_hash