From ca1e1b4b55b7636ffeb0b8382c1370c2b94e8ab3 Mon Sep 17 00:00:00 2001 From: Adrian Mugnolo and Santiago Pastorino Date: Fri, 17 Jan 2014 13:15:35 -0200 Subject: [PATCH] Extract Association login into AssociationConfiguration --- lib/active_model/serializer.rb | 10 ++-- lib/active_model/serializer/associations.rb | 53 ++++++++++---------- lib/active_model/serializer/configuration.rb | 20 ++++++++ 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index ff59a9e4..4997dd48 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -68,9 +68,9 @@ module ActiveModel attr_accessor :object, :configuration - def initialize(object, options = {}) + def initialize(object, options = {}, configuration = nil) @object = object - @configuration = InstanceConfiguration.new self.class.configuration, options + @configuration = InstanceConfiguration.new(configuration || self.class.configuration, options) end def json_key @@ -92,9 +92,9 @@ module ActiveModel included_associations = filter(associations.keys) associations.each_with_object({}) do |(name, association), hash| if included_associations.include? name - if association.embed_ids? + if association.embed_ids hash[association.key] = serialize_ids association - elsif association.embed_objects? + elsif association.embed_objects hash[association.embedded_key] = serialize association end end @@ -110,7 +110,7 @@ module ActiveModel included_associations = filter(associations.keys) associations.each_with_object({}) do |(name, association), hash| if included_associations.include? name - if association.embed_in_root? + if association.embed_in_root association_serializer = build_serializer(association) hash.merge! association_serializer.embedded_in_root_associations diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index dbf6dd2d..ded9a454 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -4,6 +4,8 @@ require 'active_model/serializer' module ActiveModel class Serializer class Association + attr_accessor :name, :configuration + def initialize(name, options = {}, configuration = nil) if options.has_key?(:include) ActiveSupport::Deprecation.warn <<-WARN @@ -13,28 +15,25 @@ module ActiveModel end @name = name.to_s - @options = options - self.embed = options.fetch(:embed) { configuration.embed } - @embed_in_root = options.fetch(:embed_in_root) { configuration.embed_in_root } - @embed_key = options[:embed_key] || :id - @key = options[:key] - @embedded_key = options[:root] || name - - serializer = @options[:serializer] - @serializer_from_options = serializer.is_a?(String) ? serializer.constantize : serializer + @configuration = AssociationConfiguration.new configuration, options end - attr_reader :name, :embed_ids, :embed_objects - attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, :root_key, :serializer_from_options, :options - alias embed_ids? embed_ids - alias embed_objects? embed_objects - alias embed_in_root? embed_in_root + extend Forwardable + def_delegators :configuration, :embed_ids, :embed_objects, :embed, :embed_in_root, :embed_key, :key, :root, :serializer + + def embedded_key + root || name + end def embed=(embed) @embed_ids = embed == :id || embed == :ids @embed_objects = embed == :object || embed == :objects end + def serializer_from_options + configuration.serializer + end + def serializer_from_object(object) Serializer.serializer_for(object) end @@ -44,14 +43,16 @@ module ActiveModel end def build_serializer(object, options = {}) - serializer_class(object).new(object, options.merge(self.options)) + serializer_class(object).new(object, options, configuration) end class HasOne < Association - def initialize(name, *args) - super - @root_key = @embedded_key.to_s.pluralize - @key ||= "#{name}_id" + def root_key + embedded_key.to_s.pluralize + end + + def key + "#{name}_id" end def serializer_class(object) @@ -60,16 +61,16 @@ module ActiveModel def build_serializer(object, options = {}) super.tap do |instance| - instance.configuration.wrap_in_array = embed_in_root? + instance.configuration.wrap_in_array = embed_in_root end end end class HasMany < Association - def initialize(name, *args) - super - @root_key = @embedded_key - @key ||= "#{name.to_s.singularize}_ids" + alias_method :root_key, :embedded_key + + def key + "#{name.to_s.singularize}_ids" end def serializer_class(object) @@ -80,9 +81,9 @@ module ActiveModel end end - def options + def build_serializer(object, options = {}) if use_array_serializer? - { each_serializer: serializer_from_options }.merge! super + super object, { each_serializer: serializer_from_options }.merge!(options), configuration else super end diff --git a/lib/active_model/serializer/configuration.rb b/lib/active_model/serializer/configuration.rb index a53873a7..86700209 100644 --- a/lib/active_model/serializer/configuration.rb +++ b/lib/active_model/serializer/configuration.rb @@ -115,5 +115,25 @@ module ActiveModel { embed: :objects, meta_key: :meta } end end + + class AssociationConfiguration < Configuration + options :embed, :embed_in_root, :embed_key, :key, :root, :serializer + + def default_options + { embed_key: :id } + end + + def serializer=(value) + @serializer = value.is_a?(String) ? value.constantize : value + end + + def embed_objects + [:objects, :object].include? embed + end + + def embed_ids + [:ids, :id].include? embed + end + end end end