From 0ba4830dee6637472f729400528746aece5cb85c Mon Sep 17 00:00:00 2001 From: Adrian Mugnolo and Santiago Pastorino Date: Fri, 10 Jan 2014 19:25:43 -0200 Subject: [PATCH] New take on configuration --- lib/active_model/serializer.rb | 25 +++--- lib/active_model/serializer/associations.rb | 6 +- lib/active_model/serializer/config.rb | 31 ------- lib/active_model/serializer/configuration.rb | 82 ++++++++++++++++++ .../active_model/serializer/config_test.rb | 86 ------------------- .../serializer/configuration_test.rb | 41 +++++++++ 6 files changed, 137 insertions(+), 134 deletions(-) delete mode 100644 lib/active_model/serializer/config.rb create mode 100644 lib/active_model/serializer/configuration.rb delete mode 100644 test/unit/active_model/serializer/config_test.rb create mode 100644 test/unit/active_model/serializer/configuration_test.rb diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index aa5598f4..e4e66d61 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -1,7 +1,7 @@ require 'active_model/array_serializer' require 'active_model/serializable' require 'active_model/serializer/associations' -require 'active_model/serializer/config' +require 'active_model/serializer/configuration' require 'active_model/serializer/dsl' require 'thread' @@ -22,22 +22,13 @@ module ActiveModel def setup @mutex.synchronize do - yield CONFIG + yield Configuration.global end end def embed(type, options={}) - CONFIG.embed = type - CONFIG.embed_in_root = true if options[:embed_in_root] || options[:include] - ActiveSupport::Deprecation.warn <<-WARN -** Notice: embed is deprecated. ** -The use of .embed method on a Serializer will be soon removed, as this should have a global scope and not a class scope. -Please use the global .setup method instead: -ActiveModel::Serializer.setup do |config| - config.embed = :#{type} - config.embed_in_root = #{CONFIG.embed_in_root || false} -end - WARN + Configuration.global.embed = type + Configuration.global.embed_in_root = true if options[:embed_in_root] || options[:include] end if RUBY_VERSION >= '2.0' @@ -74,6 +65,10 @@ end def_delegators :dsl, :attributes, :has_one, :has_many + def configuration + @configuration ||= Configuration.global.build + end + private def dsl @@ -81,6 +76,8 @@ end end end + attr_accessor :object, :scope, :root, :meta_key, :meta, :configuration + def initialize(object, options={}) @object = object @scope = options[:scope] @@ -88,8 +85,8 @@ end @meta_key = options[:meta_key] || :meta @meta = options[@meta_key] @wrap_in_array = options[:_wrap_in_array] + @configuration = self.class.configuration.build options end - attr_accessor :object, :scope, :root, :meta_key, :meta def json_key if root == true || root.nil? diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index d377119d..3defb93e 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -4,7 +4,7 @@ require 'active_model/serializer' module ActiveModel class Serializer class Association - def initialize(name, options={}) + def initialize(name, options = {}) if options.has_key?(:include) ActiveSupport::Deprecation.warn <<-WARN ** Notice: include was renamed to embed_in_root. ** @@ -13,8 +13,8 @@ module ActiveModel @name = name.to_s @options = options - self.embed = options.fetch(:embed) { CONFIG.embed } - @embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } } + self.embed = options.fetch(:embed) { Configuration.global.embed } + @embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { Configuration.global.embed_in_root } } @embed_key = options[:embed_key] || :id @key = options[:key] @embedded_key = options[:root] || name diff --git a/lib/active_model/serializer/config.rb b/lib/active_model/serializer/config.rb deleted file mode 100644 index fb204867..00000000 --- a/lib/active_model/serializer/config.rb +++ /dev/null @@ -1,31 +0,0 @@ -module ActiveModel - class Serializer - class Config - def initialize(data = {}) - @data = data - end - - def each(&block) - @data.each(&block) - end - - def clear - @data.clear - end - - def method_missing(name, *args) - name = name.to_s - return @data[name] if @data.include?(name) - match = name.match(/\A(.*?)([?=]?)\Z/) - case match[2] - when "=" - @data[match[1]] = args.first - when "?" - !!@data[match[1]] - end - end - end - - CONFIG = Config.new('embed' => :objects) # :nodoc: - end -end diff --git a/lib/active_model/serializer/configuration.rb b/lib/active_model/serializer/configuration.rb new file mode 100644 index 00000000..855e0876 --- /dev/null +++ b/lib/active_model/serializer/configuration.rb @@ -0,0 +1,82 @@ +require 'singleton' + +module ActiveModel + class Serializer + class Configuration + class Null + include Singleton + + def method_missing(*) + nil + end + + def respond_to?(*) + true + end + end + + attr_accessor :parent + + class << self + def global + @global ||= new default_options + end + + def default_options + { embed: :objects } + end + end + + def build(options = {}) + self.class.new options, self + end + + 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 + end + + def root + return_first @root, parent.root + end + + def embed + return_first @embed, parent.embed + end + + def embed_in_root + return_first @embed_in_root, parent.embed_in_root + end + + # FIXME: Get rid of this mess. + def embed_objects=(value) + @embed = :objects if value + end + + # FIXME: Get rid of this mess. + def embed_ids=(value) + @embed = :ids if value + end + + def embed_objects + [:objects, :object].include? embed + end + + def embed_ids + [:ids, :id].include? embed + end + + private + + def read_option(options, name) + options[name] || false if options.has_key? name + end + + def return_first(*values) + values.compact.first + end + end + end +end diff --git a/test/unit/active_model/serializer/config_test.rb b/test/unit/active_model/serializer/config_test.rb deleted file mode 100644 index a7f20976..00000000 --- a/test/unit/active_model/serializer/config_test.rb +++ /dev/null @@ -1,86 +0,0 @@ -require 'test_helper' - -module ActiveModel - class Serializer - class Config - class Test < Minitest::Test - def test_config_const_is_an_instance_of_config - assert_kind_of Config, CONFIG - end - - def test_config_instance - config = Config.new - config.setting1 = 'value1' - - assert_equal 'value1', config.setting1 - end - - def test_each_config - config = Config.new - config.setting1 = 'value1' - config.setting2 = 'value2' - - actual = {} - - config.each do |k, v| - actual[k] = v - end - - assert_equal({ 'setting1' => 'value1', 'setting2' => 'value2' }, actual) - end - end - - class ConfigTest < Minitest::Test - def test_setup - Serializer.setup do |config| - config.a = 'v1' - config.b = 'v2' - end - - assert_equal 'v1', CONFIG.a - assert_equal 'v2', CONFIG.b - ensure - CONFIG.clear - end - - def test_config_accessors - Serializer.setup do |config| - config.foo = 'v1' - config.bar = 'v2' - end - - assert_equal 'v1', CONFIG.foo - assert_equal 'v2', CONFIG.bar - ensure - CONFIG.clear - end - - def test_acessor_when_nil - assert_nil CONFIG.foo - CONFIG.foo = 1 - assert_equal 1, CONFIG.foo - assert_nil CONFIG.bar - end - end - - class ApplyConfigTest < Minitest::Test - def test_apply_config_to_associations - CONFIG.embed = :ids - CONFIG.embed_in_root = true - - association = PostSerializer._associations[:comments] - old_association = association.dup - - association.send :initialize, association.name, association.options - - assert association.embed_ids? - assert !association.embed_objects? - assert association.embed_in_root - ensure - PostSerializer._associations[:comments] = old_association - CONFIG.clear - end - end - end - end -end diff --git a/test/unit/active_model/serializer/configuration_test.rb b/test/unit/active_model/serializer/configuration_test.rb new file mode 100644 index 00000000..1d99fd2f --- /dev/null +++ b/test/unit/active_model/serializer/configuration_test.rb @@ -0,0 +1,41 @@ +require 'test_helper' + +module ActiveModel + class Serializer + class Configuration + class GlobalTest < Minitest::Test + def test_returns_global_configuration + assert_kind_of Configuration, Configuration.global + end + + def test_global_configuration_returns_the_same_instance + assert_equal Configuration.global.object_id, Configuration.global.object_id + end + + def test_global_configuration_has_default_options_set + assert Configuration.default_options.all? do |name, value| + Configuration.global.send(name) == value + end + end + end + + class OptionsTest < Minitest::Test + def setup + @configuration = Configuration.global.build(root: 'root', embed: :ids, embed_in_root: false) + end + + def test_configuration_has_root_option + assert_equal 'root', @configuration.root + end + + def test_configuration_has_embed_option + assert_equal :ids, @configuration.embed + end + + def test_configuration_has_embed_in_root_option + assert_equal false, @configuration.embed_in_root + end + end + end + end +end