From 64ed05c484dc0add53183579a347b13d138ee944 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 7 May 2013 17:51:56 -0700 Subject: [PATCH 01/38] Define serializer as DefaultSerializer if not set --- lib/active_model/array_serializer.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index 518323ca..30e7f29e 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -81,9 +81,11 @@ module ActiveModel serializer = @options[:each_serializer] elsif item.respond_to?(:active_model_serializer) serializer = item.active_model_serializer + else + serializer = DefaultSerializer end - serializable = serializer ? serializer.new(item, @options) : DefaultSerializer.new(item, @options) + serializable = serializer.new(item, @options) if serializable.respond_to?(:serializable_hash) serializable.serializable_hash From 0e876624ec84651cc473fdb691438c099dc1f3c7 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 May 2013 12:57:07 -0700 Subject: [PATCH 02/38] Move reusable code to a module --- lib/active_model/array_serializer.rb | 34 ++++------------------------ lib/active_model/serializable.rb | 34 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 lib/active_model/serializable.rb diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index 30e7f29e..7442390a 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -1,3 +1,4 @@ +require 'active_model/serializable' require "active_support/core_ext/class/attribute" require 'active_support/dependencies' require 'active_support/descendants_tracker' @@ -15,6 +16,8 @@ module ActiveModel class ArraySerializer extend ActiveSupport::DescendantsTracker + include ActiveModel::Serializable + attr_reader :object, :options class_attribute :root @@ -33,35 +36,8 @@ module ActiveModel @object, @options = object, options end - def meta_key - @options[:meta_key].try(:to_sym) || :meta - end - - def include_meta(hash) - hash[meta_key] = @options[:meta] if @options.has_key?(:meta) - end - - def as_json(*args) - @options[:hash] = hash = {} - @options[:unique_values] = {} - - if root = @options[:root] - hash.merge!(root => serializable_array) - include_meta hash - hash - else - serializable_array - end - end - - def to_json(*args) - if perform_caching? - cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'to-json']) do - super - end - else - super - end + def serialize + serializable_array end def serializable_array diff --git a/lib/active_model/serializable.rb b/lib/active_model/serializable.rb new file mode 100644 index 00000000..d288df44 --- /dev/null +++ b/lib/active_model/serializable.rb @@ -0,0 +1,34 @@ +module ActiveModel + module Serializable + def meta_key + options[:meta_key].try(:to_sym) || :meta + end + + def include_meta(hash) + hash[meta_key] = options[:meta] if options.has_key?(:meta) + end + + def as_json(*args) + options[:hash] = hash = {} + options[:unique_values] = {} + + if root = options[:root] + hash.merge!(root => serialize) + include_meta hash + hash + else + serialize + end + end + + def to_json(*args) + if perform_caching? + cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'to-json']) do + super + end + else + super + end + end + end +end From 76fead041f99f712b515f36cb9a7912abe184205 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 May 2013 13:02:03 -0700 Subject: [PATCH 03/38] Make Serializer reuse Serializable --- lib/active_model/serializable.rb | 8 +++---- lib/active_model/serializer.rb | 36 +++++++------------------------- 2 files changed, 12 insertions(+), 32 deletions(-) diff --git a/lib/active_model/serializable.rb b/lib/active_model/serializable.rb index d288df44..07f53ffa 100644 --- a/lib/active_model/serializable.rb +++ b/lib/active_model/serializable.rb @@ -8,11 +8,11 @@ module ActiveModel hash[meta_key] = options[:meta] if options.has_key?(:meta) end - def as_json(*args) - options[:hash] = hash = {} - options[:unique_values] = {} + def as_json(args={}) + if root = args[:root] || options[:root] + options[:hash] = hash = {} + options[:unique_values] = {} - if root = options[:root] hash.merge!(root => serialize) include_meta hash hash diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 281af425..a085775d 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -1,3 +1,4 @@ +require 'active_model/serializable' require "active_support/core_ext/class/attribute" require "active_support/core_ext/module/anonymous" require 'active_support/dependencies' @@ -40,6 +41,8 @@ module ActiveModel class Serializer extend ActiveSupport::DescendantsTracker + include ActiveModel::Serializable + INCLUDE_METHODS = {} INSTRUMENT = { :serialize => :"serialize.serializer", :associations => :"associations.serializer" } @@ -316,37 +319,14 @@ module ActiveModel @options[:url_options] || {} end - def meta_key - @options[:meta_key].try(:to_sym) || :meta - end - - def include_meta(hash) - hash[meta_key] = @options[:meta] if @options.has_key?(:meta) - end - - def to_json(*args) - if perform_caching? - cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'to-json']) do - super - end - else - super - end - end - # Returns a json representation of the serializable # object including the root. - def as_json(options={}) - if root = options.fetch(:root, @options.fetch(:root, root_name)) - @options[:hash] = hash = {} - @options[:unique_values] = {} + def as_json(args={}) + super(root: args.fetch(:root, options.fetch(:root, root_name))) + end - hash.merge!(root => serializable_hash) - include_meta hash - hash - else - serializable_hash - end + def serialize + serializable_hash end # Returns a hash representation of the serializable From aaa08c25ef7cb38053f11ec1b3b892e17b6f385b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 May 2013 17:49:30 -0700 Subject: [PATCH 04/38] Make include_meta and meta_key private --- lib/active_model/serializable.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/active_model/serializable.rb b/lib/active_model/serializable.rb index 07f53ffa..47300530 100644 --- a/lib/active_model/serializable.rb +++ b/lib/active_model/serializable.rb @@ -1,13 +1,5 @@ module ActiveModel module Serializable - def meta_key - options[:meta_key].try(:to_sym) || :meta - end - - def include_meta(hash) - hash[meta_key] = options[:meta] if options.has_key?(:meta) - end - def as_json(args={}) if root = args[:root] || options[:root] options[:hash] = hash = {} @@ -30,5 +22,15 @@ module ActiveModel super end end + + private + + def include_meta(hash) + hash[meta_key] = options[:meta] if options.has_key?(:meta) + end + + def meta_key + options[:meta_key].try(:to_sym) || :meta + end end end From f179a27ed793aa3b9a93dd666364134a18f43edf Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 15:53:39 -0700 Subject: [PATCH 05/38] Add docs to serializable --- lib/active_model/serializable.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/active_model/serializable.rb b/lib/active_model/serializable.rb index 47300530..cf1cbaa7 100644 --- a/lib/active_model/serializable.rb +++ b/lib/active_model/serializable.rb @@ -1,4 +1,27 @@ +require 'active_support/core_ext/object/to_json' + module ActiveModel + # Enable classes to Classes including this module to serialize themselves by implementing a serialize method and an options method. + # + # Example: + # + # require 'active_model_serializers' + # + # class MySerializer + # include ActiveModel::Serializable + # + # def initialize + # @options = {} + # end + # + # attr_reader :options + # + # def serialize + # { a: 1 } + # end + # end + # + # puts MySerializer.new.to_json module Serializable def as_json(args={}) if root = args[:root] || options[:root] From 1a8709d71c8e26caf26d0f28d8f3afa93a1cade2 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 May 2013 15:08:58 -0700 Subject: [PATCH 06/38] Move caching to a new module --- lib/active_model/array_serializer.rb | 23 +++------------- lib/active_model/serializable.rb | 10 ------- lib/active_model/serializer.rb | 31 +++++---------------- lib/active_model/serializer/caching.rb | 37 ++++++++++++++++++++++++++ test/caching_test.rb | 4 +-- 5 files changed, 49 insertions(+), 56 deletions(-) create mode 100644 lib/active_model/serializer/caching.rb diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index 7442390a..5f0df670 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -1,4 +1,5 @@ require 'active_model/serializable' +require 'active_model/serializer/caching' require "active_support/core_ext/class/attribute" require 'active_support/dependencies' require 'active_support/descendants_tracker' @@ -17,6 +18,7 @@ module ActiveModel extend ActiveSupport::DescendantsTracker include ActiveModel::Serializable + include ActiveModel::Serializer::Caching attr_reader :object, :options @@ -36,22 +38,11 @@ module ActiveModel @object, @options = object, options end - def serialize + def serialize_object serializable_array end def serializable_array - if perform_caching? - cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'serializable-array']) do - _serializable_array - end - else - _serializable_array - end - end - - private - def _serializable_array @object.map do |item| if @options.has_key? :each_serializer serializer = @options[:each_serializer] @@ -70,13 +61,5 @@ module ActiveModel end end end - - def expand_cache_key(*args) - ActiveSupport::Cache.expand_cache_key(args) - end - - def perform_caching? - perform_caching && cache && respond_to?(:cache_key) - end end end diff --git a/lib/active_model/serializable.rb b/lib/active_model/serializable.rb index cf1cbaa7..7122ae20 100644 --- a/lib/active_model/serializable.rb +++ b/lib/active_model/serializable.rb @@ -36,16 +36,6 @@ module ActiveModel end end - def to_json(*args) - if perform_caching? - cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'to-json']) do - super - end - else - super - end - end - private def include_meta(hash) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index a085775d..2dc8d843 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -1,4 +1,5 @@ require 'active_model/serializable' +require 'active_model/serializer/caching' require "active_support/core_ext/class/attribute" require "active_support/core_ext/module/anonymous" require 'active_support/dependencies' @@ -42,6 +43,7 @@ module ActiveModel extend ActiveSupport::DescendantsTracker include ActiveModel::Serializable + include ActiveModel::Serializer::Caching INCLUDE_METHODS = {} INSTRUMENT = { :serialize => :"serialize.serializer", :associations => :"associations.serializer" } @@ -73,7 +75,6 @@ module ActiveModel class_attribute :perform_caching class << self - # set perform caching like root def cached(value = true) self.perform_caching = value end @@ -325,20 +326,17 @@ module ActiveModel super(root: args.fetch(:root, options.fetch(:root, root_name))) end - def serialize + def serialize_object serializable_hash end # Returns a hash representation of the serializable # object without the root. def serializable_hash - if perform_caching? - cache.fetch expand_cache_key([self.class.to_s.underscore, cache_key, 'serializable-hash']) do - _serializable_hash - end - else - _serializable_hash - end + return nil if @object.nil? + @node = attributes + include_associations! if _embed + @node end def include_associations! @@ -453,21 +451,6 @@ module ActiveModel alias :read_attribute_for_serialization :send - def _serializable_hash - return nil if @object.nil? - @node = attributes - include_associations! if _embed - @node - end - - def perform_caching? - perform_caching && cache && respond_to?(:cache_key) - end - - def expand_cache_key(*args) - ActiveSupport::Cache.expand_cache_key(args) - end - # Use ActiveSupport::Notifications to send events to external systems. # The event name is: name.class_name.serializer def instrument(name, payload = {}, &block) diff --git a/lib/active_model/serializer/caching.rb b/lib/active_model/serializer/caching.rb new file mode 100644 index 00000000..50fcf7b5 --- /dev/null +++ b/lib/active_model/serializer/caching.rb @@ -0,0 +1,37 @@ +module ActiveModel + class Serializer + module Caching + def to_json(*args) + if caching_enabled? + key = expand_cache_key([self.class.to_s.underscore, cache_key, 'to-json']) + cache.fetch key do + super + end + else + super + end + end + + def serialize(*args) + if caching_enabled? + key = expand_cache_key([self.class.to_s.underscore, cache_key, 'serialize']) + cache.fetch key do + serialize_object + end + else + serialize_object + end + end + + private + + def caching_enabled? + perform_caching && cache && respond_to?(:cache_key) + end + + def expand_cache_key(*args) + ActiveSupport::Cache.expand_cache_key(args) + end + end + end +end diff --git a/test/caching_test.rb b/test/caching_test.rb index 869f0f93..ee1dd263 100644 --- a/test/caching_test.rb +++ b/test/caching_test.rb @@ -68,7 +68,7 @@ class CachingTest < ActiveModel::TestCase instance.to_json - assert_equal(instance.serializable_hash, serializer.cache.read('serializer/Adam/serializable-hash')) + assert_equal(instance.serializable_hash, serializer.cache.read('serializer/Adam/serialize')) assert_equal(instance.to_json, serializer.cache.read('serializer/Adam/to-json')) end @@ -90,7 +90,7 @@ class CachingTest < ActiveModel::TestCase instance.to_json - assert_equal instance.serializable_array, serializer.cache.read('array_serializer/cache-key/serializable-array') + assert_equal instance.serializable_array, serializer.cache.read('array_serializer/cache-key/serialize') assert_equal instance.to_json, serializer.cache.read('array_serializer/cache-key/to-json') end end From 460a2509843d0025ba459c633efda03b2c6bdbea Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 13 May 2013 11:50:54 -0700 Subject: [PATCH 07/38] Get rid of refine --- lib/active_model/serializer.rb | 10 ++++--- lib/active_model/serializer/associations.rb | 30 --------------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 2dc8d843..855e020a 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -129,7 +129,7 @@ module ActiveModel define_include_method attr - self._associations[attr] = klass.refine(attr, options) + self._associations[attr] = [klass, options] end end @@ -217,8 +217,8 @@ module ActiveModel end associations = {} - _associations.each do |attr, association_class| - association = association_class.new(attr, self) + _associations.each do |attr, (association_class, options)| + association = association_class.new(attr, self, options) if model_association = klass.reflect_on_association(association.name) # Real association. @@ -381,8 +381,10 @@ module ActiveModel end end + klass, opts = _associations[name] association_class = - if klass = _associations[name] + if klass + options = opts.merge options klass elsif value.respond_to?(:to_ary) Associations::HasMany diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 8606b930..35c0dc0e 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -2,34 +2,6 @@ module ActiveModel class Serializer module Associations #:nodoc: class Config #:nodoc: - class_attribute :options - - def self.refine(name, class_options) - current_class = self - - Class.new(self) do - singleton_class.class_eval do - define_method(:to_s) do - "(subclass of #{current_class.name})" - end - - alias inspect to_s - end - - self.options = class_options - - # cache the root so we can reuse it without falling back on a per-instance basis - begin - self.options[:root] ||= self.new(name, nil).root - rescue - # this could fail if it needs a valid source, for example a polymorphic association - end - - end - end - - self.options = {} - def initialize(name, source, options={}) @name = name @source = source @@ -39,8 +11,6 @@ module ActiveModel def option(key, default=nil) if @options.key?(key) @options[key] - elsif self.class.options.key?(key) - self.class.options[key] else default end From 5017fb686a1a2b7190ce920cb15ddf537ead83bb Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 13 May 2013 16:00:16 -0700 Subject: [PATCH 08/38] Associations doesn't depend on source serializer anymore --- lib/active_model/serializer.rb | 4 ++++ lib/active_model/serializer/associations.rb | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 855e020a..1e9787ba 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -392,6 +392,10 @@ module ActiveModel Associations::HasOne end + options[:value] ||= send(name) + options[:embed] = _embed unless options.key?(:embed) + options[:include] = _root_embed unless options.key?(:include) + options[:serializer_options] = self.options association = association_class.new(name, self, options) if association.embed_ids? diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 35c0dc0e..ae880246 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -38,19 +38,19 @@ module ActiveModel end def associated_object - option(:value) || source_serializer.send(name) + option(:value) end def embed_ids? - [:id, :ids].include? option(:embed, source_serializer._embed) + [:id, :ids].include? option(:embed) end def embed_objects? - [:object, :objects].include? option(:embed, source_serializer._embed) + [:object, :objects].include? option(:embed) end def embed_in_root? - option(:include, source_serializer._root_embed) + option(:include) end def embeddable? @@ -61,9 +61,9 @@ module ActiveModel def find_serializable(object) if target_serializer - target_serializer.new(object, source_serializer.options) + target_serializer.new(object, option(:serializer_options)) elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer) - ams.new(object, source_serializer.options) + ams.new(object, option(:serializer_options)) else object end From ea3566955c59acaf2f2a0f8cecee1bd930d26fbd Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 16:30:41 -0700 Subject: [PATCH 09/38] Remove option method just use the reader --- lib/active_model/serializer/associations.rb | 46 +++++++++------------ 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index ae880246..3165258b 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -8,16 +8,8 @@ module ActiveModel @options = options end - def option(key, default=nil) - if @options.key?(key) - @options[key] - else - default - end - end - def target_serializer - serializer = option(:serializer) + serializer = options[:serializer] serializer.is_a?(String) ? serializer.constantize : serializer end @@ -26,31 +18,31 @@ module ActiveModel end def key - option(:key) || @name + options[:key] || @name end def root - option(:root) || @name + options[:root] || @name end def name - option(:name) || @name + options[:name] || @name end def associated_object - option(:value) + options[:value] end def embed_ids? - [:id, :ids].include? option(:embed) + [:id, :ids].include? options[:embed] end def embed_objects? - [:object, :objects].include? option(:embed) + [:object, :objects].include? options[:embed] end def embed_in_root? - option(:include) + options[:include] end def embeddable? @@ -61,18 +53,20 @@ module ActiveModel def find_serializable(object) if target_serializer - target_serializer.new(object, option(:serializer_options)) + target_serializer.new(object, options[:serializer_options]) elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer) - ams.new(object, option(:serializer_options)) + ams.new(object, options[:serializer_options]) else object end end + + attr_reader :options end class HasMany < Config #:nodoc: def key - if key = option(:key) + if key = options[:key] key elsif embed_ids? "#{@name.to_s.singularize}_ids".to_sym @@ -82,7 +76,7 @@ module ActiveModel end def embed_key - if key = option(:embed_key) + if key = options[:embed_key] key else :id @@ -103,7 +97,7 @@ module ActiveModel def serialize_ids ids_key = "#{@name.to_s.singularize}_ids".to_sym - if !option(:embed_key) && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(ids_key) + if !options[:embed_key] && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(ids_key) source_serializer.object.read_attribute_for_serialization(ids_key) else associated_object.map do |item| @@ -123,11 +117,11 @@ module ActiveModel end def polymorphic? - option :polymorphic + options[:polymorphic] end def root - if root = option(:root) + if root = options[:root] root elsif polymorphic? associated_object.class.to_s.pluralize.demodulize.underscore.to_sym @@ -137,7 +131,7 @@ module ActiveModel end def key - if key = option(:key) + if key = options[:key] key elsif embed_ids? && !polymorphic? "#{@name}_id".to_sym @@ -147,7 +141,7 @@ module ActiveModel end def embed_key - if key = option(:embed_key) + if key = options[:embed_key] key else :id @@ -189,7 +183,7 @@ module ActiveModel else nil end - elsif !option(:embed_key) && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(id_key) + elsif !options[:embed_key] && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(id_key) source_serializer.object.read_attribute_for_serialization(id_key) elsif associated_object associated_object.read_attribute_for_serialization(embed_key) From a41de0286ff0890596fe0e8d37912db96edd9453 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 13 May 2013 17:37:36 -0700 Subject: [PATCH 10/38] Passing options[:hash] is not public API of include! --- lib/active_model/serializer.rb | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 1e9787ba..c1cd4990 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -352,23 +352,8 @@ module ActiveModel end def include!(name, options={}) - # Make sure that if a special options[:hash] was passed in, we generate - # a new unique values hash and don't clobber the original. If the hash - # passed in is the same as the current options hash, use the current - # unique values. - # - # TODO: Should passing in a Hash even be public API here? - unique_values = - if hash = options[:hash] - if @options[:hash] == hash - @options[:unique_values] ||= {} - else - {} - end - else - hash = @options[:hash] - @options[:unique_values] ||= {} - end + hash = @options[:hash] + unique_values = @options[:unique_values] ||= {} node = options[:node] ||= @node value = options[:value] From 9f5e872621758f58b2d88cd6dc148c17add0250a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 May 2013 15:50:40 -0700 Subject: [PATCH 11/38] Extract id_key to a method --- lib/active_model/serializer/associations.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 3165258b..6b4460e6 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -69,7 +69,7 @@ module ActiveModel if key = options[:key] key elsif embed_ids? - "#{@name.to_s.singularize}_ids".to_sym + id_key else @name end @@ -83,6 +83,10 @@ module ActiveModel end end + def id_key + "#{@name.to_s.singularize}_ids".to_sym + end + def serialize associated_object.map do |item| find_serializable(item).serializable_hash @@ -96,9 +100,8 @@ module ActiveModel end def serialize_ids - ids_key = "#{@name.to_s.singularize}_ids".to_sym - if !options[:embed_key] && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(ids_key) - source_serializer.object.read_attribute_for_serialization(ids_key) + if !options[:embed_key] && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(id_key) + source_serializer.object.read_attribute_for_serialization(id_key) else associated_object.map do |item| item.read_attribute_for_serialization(embed_key) @@ -134,7 +137,7 @@ module ActiveModel if key = options[:key] key elsif embed_ids? && !polymorphic? - "#{@name}_id".to_sym + id_key else @name end @@ -148,6 +151,10 @@ module ActiveModel end end + def id_key + "#{@name}_id".to_sym + end + def polymorphic_key associated_object.class.to_s.demodulize.underscore.to_sym end @@ -172,8 +179,6 @@ module ActiveModel end def serialize_ids - id_key = "#{@name}_id".to_sym - if polymorphic? if associated_object { From 0917148617707163b7fb7700dad56863bcc9c94d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 May 2013 16:20:51 -0700 Subject: [PATCH 12/38] serialize_ids doesn't use source serializer and it's object --- lib/active_model/serializer.rb | 7 ++++++- lib/active_model/serializer/associations.rb | 23 +++++++-------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index c1cd4990..8aa8b719 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -384,7 +384,12 @@ module ActiveModel association = association_class.new(name, self, options) if association.embed_ids? - node[association.key] = association.serialize_ids + node[association.key] = + if options[:embed_key] || self.respond_to?(name) || !self.object.respond_to?(association.id_key) + association.serialize_ids + else + self.object.read_attribute_for_serialization(association.id_key) + end if association.embed_in_root? && hash.nil? raise IncludeError.new(self.class, association.name) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 6b4460e6..667774fb 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -100,12 +100,8 @@ module ActiveModel end def serialize_ids - if !options[:embed_key] && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(id_key) - source_serializer.object.read_attribute_for_serialization(id_key) - else - associated_object.map do |item| - item.read_attribute_for_serialization(embed_key) - end + associated_object.map do |item| + item.read_attribute_for_serialization(embed_key) end end end @@ -179,21 +175,16 @@ module ActiveModel end def serialize_ids - if polymorphic? - if associated_object + if associated_object + id = associated_object.read_attribute_for_serialization(embed_key) + if polymorphic? { :type => polymorphic_key, - :id => associated_object.read_attribute_for_serialization(embed_key) + :id => id } else - nil + id end - elsif !options[:embed_key] && !source_serializer.respond_to?(@name.to_s) && source_serializer.object.respond_to?(id_key) - source_serializer.object.read_attribute_for_serialization(id_key) - elsif associated_object - associated_object.read_attribute_for_serialization(embed_key) - else - nil end end end From baa690a01a667720c8af4e0a125be2e7e2966026 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 May 2013 16:24:03 -0700 Subject: [PATCH 13/38] Move if object to the top --- lib/active_model/serializer/associations.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 667774fb..2ee98f65 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -158,13 +158,15 @@ module ActiveModel def serialize object = associated_object - if object && polymorphic? - { - :type => polymorphic_key, - polymorphic_key => find_serializable(object).serializable_hash - } - elsif object - find_serializable(object).serializable_hash + if object + if polymorphic? + { + :type => polymorphic_key, + polymorphic_key => find_serializable(object).serializable_hash + } + else + find_serializable(object).serializable_hash + end end end From c1e710aae130d6f99840ad7734b01d58afb31ad1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 May 2013 16:24:59 -0700 Subject: [PATCH 14/38] Save result of calling associated_object in a local var --- lib/active_model/serializer/associations.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 2ee98f65..30ca5f4f 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -177,8 +177,10 @@ module ActiveModel end def serialize_ids - if associated_object - id = associated_object.read_attribute_for_serialization(embed_key) + object = associated_object + + if object + id = object.read_attribute_for_serialization(embed_key) if polymorphic? { :type => polymorphic_key, From c04d452823be8981d5e67967654d66e072383558 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 16:31:33 -0700 Subject: [PATCH 15/38] Associations doesn't depend on the source serializer anymore :) --- lib/active_model/serializer.rb | 4 ++-- lib/active_model/serializer/associations.rb | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 8aa8b719..b9a892b1 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -218,7 +218,7 @@ module ActiveModel associations = {} _associations.each do |attr, (association_class, options)| - association = association_class.new(attr, self, options) + association = association_class.new(attr, options) if model_association = klass.reflect_on_association(association.name) # Real association. @@ -381,7 +381,7 @@ module ActiveModel options[:embed] = _embed unless options.key?(:embed) options[:include] = _root_embed unless options.key?(:include) options[:serializer_options] = self.options - association = association_class.new(name, self, options) + association = association_class.new(name, options) if association.embed_ids? node[association.key] = diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 30ca5f4f..140c056a 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -2,9 +2,8 @@ module ActiveModel class Serializer module Associations #:nodoc: class Config #:nodoc: - def initialize(name, source, options={}) + def initialize(name, options={}) @name = name - @source = source @options = options end @@ -13,10 +12,6 @@ module ActiveModel serializer.is_a?(String) ? serializer.constantize : serializer end - def source_serializer - @source - end - def key options[:key] || @name end From e273a2fb37f508919765a16b2396eab4524993e1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 May 2013 17:03:59 -0700 Subject: [PATCH 16/38] Use a third argument to pass serializer_options --- lib/active_model/serializer.rb | 3 +-- lib/active_model/serializer/associations.rb | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index b9a892b1..02a25c56 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -380,8 +380,7 @@ module ActiveModel options[:value] ||= send(name) options[:embed] = _embed unless options.key?(:embed) options[:include] = _root_embed unless options.key?(:include) - options[:serializer_options] = self.options - association = association_class.new(name, options) + association = association_class.new(name, options, self.options) if association.embed_ids? node[association.key] = diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 140c056a..c651417d 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -2,9 +2,10 @@ module ActiveModel class Serializer module Associations #:nodoc: class Config #:nodoc: - def initialize(name, options={}) + def initialize(name, options={}, serializer_options={}) @name = name @options = options + @serializer_options = serializer_options end def target_serializer @@ -48,15 +49,15 @@ module ActiveModel def find_serializable(object) if target_serializer - target_serializer.new(object, options[:serializer_options]) + target_serializer.new(object, serializer_options) elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer) - ams.new(object, options[:serializer_options]) + ams.new(object, serializer_options) else object end end - attr_reader :options + attr_reader :options, :serializer_options end class HasMany < Config #:nodoc: From 0b9f69529f65bef0662502a96de7a19cc221fe06 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 May 2013 17:05:41 -0700 Subject: [PATCH 17/38] Add default_embed_options --- lib/active_model/serializer.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 02a25c56..4fec41a5 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -377,9 +377,8 @@ module ActiveModel Associations::HasOne end + options = default_embed_options.merge!(options) options[:value] ||= send(name) - options[:embed] = _embed unless options.key?(:embed) - options[:include] = _root_embed unless options.key?(:include) association = association_class.new(name, options, self.options) if association.embed_ids? @@ -452,6 +451,15 @@ module ActiveModel event_name = INSTRUMENT[name] ActiveSupport::Notifications.instrument(event_name, payload, &block) end + + private + + def default_embed_options + { + :embed => _embed, + :include => _root_embed + } + end end # DefaultSerializer From 251fdc7ba46776f9ac01b281844eddc1e2f6df33 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 May 2013 17:26:38 -0700 Subject: [PATCH 18/38] Rename opts to klass_options --- lib/active_model/serializer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 4fec41a5..3468a09d 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -366,10 +366,10 @@ module ActiveModel end end - klass, opts = _associations[name] + klass, klass_options = _associations[name] association_class = if klass - options = opts.merge options + options = klass_options.merge options klass elsif value.respond_to?(:to_ary) Associations::HasMany From 2b22acff53587710594cf56846eeda82579799d8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 12:57:30 -0700 Subject: [PATCH 19/38] Use the readers instead of accessing the ivar directly --- lib/active_model/array_serializer.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index 5f0df670..f6474323 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -35,7 +35,8 @@ module ActiveModel end def initialize(object, options={}) - @object, @options = object, options + @object = object + @options = options end def serialize_object @@ -43,16 +44,16 @@ module ActiveModel end def serializable_array - @object.map do |item| - if @options.has_key? :each_serializer - serializer = @options[:each_serializer] + object.map do |item| + if options.has_key? :each_serializer + serializer = options[:each_serializer] elsif item.respond_to?(:active_model_serializer) serializer = item.active_model_serializer else serializer = DefaultSerializer end - serializable = serializer.new(item, @options) + serializable = serializer.new(item, options) if serializable.respond_to?(:serializable_hash) serializable.serializable_hash From 03669a74bcb854352a795ac188a4f25b193a15b3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 14:23:09 -0700 Subject: [PATCH 20/38] Associations::Config is now Associations::Base --- lib/active_model/serializer/associations.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index c651417d..42bc7546 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -1,7 +1,7 @@ module ActiveModel class Serializer module Associations #:nodoc: - class Config #:nodoc: + class Base #:nodoc: def initialize(name, options={}, serializer_options={}) @name = name @options = options @@ -60,7 +60,7 @@ module ActiveModel attr_reader :options, :serializer_options end - class HasMany < Config #:nodoc: + class HasMany < Base #:nodoc: def key if key = options[:key] key @@ -102,7 +102,7 @@ module ActiveModel end end - class HasOne < Config #:nodoc: + class HasOne < Base #:nodoc: def embeddable? if polymorphic? && associated_object.nil? false From 85bf3d2f3d36736f22e2829a64e637bac2e956f9 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 15:43:37 -0700 Subject: [PATCH 21/38] Move duplicated code to the Base class --- lib/active_model/serializer/associations.rb | 24 +++++++-------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 42bc7546..1a04eda3 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -45,6 +45,14 @@ module ActiveModel !associated_object.nil? end + def embed_key + if key = options[:embed_key] + key + else + :id + end + end + protected def find_serializable(object) @@ -71,14 +79,6 @@ module ActiveModel end end - def embed_key - if key = options[:embed_key] - key - else - :id - end - end - def id_key "#{@name.to_s.singularize}_ids".to_sym end @@ -135,14 +135,6 @@ module ActiveModel end end - def embed_key - if key = options[:embed_key] - key - else - :id - end - end - def id_key "#{@name}_id".to_sym end From f9e189e9d71d86b64e00901769a0ad92b33e9624 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 15:50:23 -0700 Subject: [PATCH 22/38] Rename associated_object to object --- lib/active_model/serializer/associations.rb | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 1a04eda3..ce6c87cd 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -25,7 +25,7 @@ module ActiveModel options[:name] || @name end - def associated_object + def object options[:value] end @@ -42,7 +42,7 @@ module ActiveModel end def embeddable? - !associated_object.nil? + !object.nil? end def embed_key @@ -84,19 +84,19 @@ module ActiveModel end def serialize - associated_object.map do |item| + object.map do |item| find_serializable(item).serializable_hash end end def serializables - associated_object.map do |item| + object.map do |item| find_serializable(item) end end def serialize_ids - associated_object.map do |item| + object.map do |item| item.read_attribute_for_serialization(embed_key) end end @@ -104,7 +104,7 @@ module ActiveModel class HasOne < Base #:nodoc: def embeddable? - if polymorphic? && associated_object.nil? + if polymorphic? && object.nil? false else true @@ -119,7 +119,7 @@ module ActiveModel if root = options[:root] root elsif polymorphic? - associated_object.class.to_s.pluralize.demodulize.underscore.to_sym + object.class.to_s.pluralize.demodulize.underscore.to_sym else @name.to_s.pluralize.to_sym end @@ -140,12 +140,10 @@ module ActiveModel end def polymorphic_key - associated_object.class.to_s.demodulize.underscore.to_sym + object.class.to_s.demodulize.underscore.to_sym end def serialize - object = associated_object - if object if polymorphic? { @@ -159,14 +157,11 @@ module ActiveModel end def serializables - object = associated_object value = object && find_serializable(object) value ? [value] : [] end def serialize_ids - object = associated_object - if object id = object.read_attribute_for_serialization(embed_key) if polymorphic? From 0b648fceac183b8980c97a77113b91d5b11f7fda Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 15:51:55 -0700 Subject: [PATCH 23/38] Use private instead of protected, we don't use explicit receivers --- lib/active_model/serializer/associations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index ce6c87cd..f1f7a5b8 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -53,7 +53,7 @@ module ActiveModel end end - protected + private def find_serializable(object) if target_serializer From 2dd0090f13268e0470d0368a9f3776ea8fc8d572 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 16:02:03 -0700 Subject: [PATCH 24/38] Reorder methods --- lib/active_model/serializer/associations.rb | 88 +++++++++++---------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index f1f7a5b8..711eac4f 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -8,9 +8,8 @@ module ActiveModel @serializer_options = serializer_options end - def target_serializer - serializer = options[:serializer] - serializer.is_a?(String) ? serializer.constantize : serializer + def name + options[:name] || @name end def key @@ -21,14 +20,6 @@ module ActiveModel options[:root] || @name end - def name - options[:name] || @name - end - - def object - options[:value] - end - def embed_ids? [:id, :ids].include? options[:embed] end @@ -45,6 +36,12 @@ module ActiveModel !object.nil? end + private + + def object + options[:value] + end + def embed_key if key = options[:embed_key] key @@ -53,7 +50,10 @@ module ActiveModel end end - private + def target_serializer + serializer = options[:serializer] + serializer.is_a?(String) ? serializer.constantize : serializer + end def find_serializable(object) if target_serializer @@ -83,18 +83,18 @@ module ActiveModel "#{@name.to_s.singularize}_ids".to_sym end - def serialize - object.map do |item| - find_serializable(item).serializable_hash - end - end - def serializables object.map do |item| find_serializable(item) end end + def serialize + object.map do |item| + find_serializable(item).serializable_hash + end + end + def serialize_ids object.map do |item| item.read_attribute_for_serialization(embed_key) @@ -103,18 +103,16 @@ module ActiveModel end class HasOne < Base #:nodoc: - def embeddable? - if polymorphic? && object.nil? - false + def key + if key = options[:key] + key + elsif embed_ids? && !polymorphic? + id_key else - true + @name end end - def polymorphic? - options[:polymorphic] - end - def root if root = options[:root] root @@ -125,22 +123,21 @@ module ActiveModel end end - def key - if key = options[:key] - key - elsif embed_ids? && !polymorphic? - id_key - else - @name - end - end - def id_key "#{@name}_id".to_sym end - def polymorphic_key - object.class.to_s.demodulize.underscore.to_sym + def embeddable? + if polymorphic? && object.nil? + false + else + true + end + end + + def serializables + value = object && find_serializable(object) + value ? [value] : [] end def serialize @@ -156,11 +153,6 @@ module ActiveModel end end - def serializables - value = object && find_serializable(object) - value ? [value] : [] - end - def serialize_ids if object id = object.read_attribute_for_serialization(embed_key) @@ -174,6 +166,16 @@ module ActiveModel end end end + + private + + def polymorphic? + options[:polymorphic] + end + + def polymorphic_key + object.class.to_s.demodulize.underscore.to_sym + end end end end From ea6d712cc85fdabccca6e0631baf9562afc0a484 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 16:04:29 -0700 Subject: [PATCH 25/38] key method is defined on subclasses --- lib/active_model/serializer/associations.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 711eac4f..54967401 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -12,10 +12,6 @@ module ActiveModel options[:name] || @name end - def key - options[:key] || @name - end - def root options[:root] || @name end From eb5b27de695407e23e7fd33fb6785b395c5f9de1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 16:13:26 -0700 Subject: [PATCH 26/38] Initialize things in the initialize method and define readers --- lib/active_model/serializer/associations.rb | 41 ++++++++------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 54967401..0583d0c0 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -3,29 +3,26 @@ module ActiveModel module Associations #:nodoc: class Base #:nodoc: def initialize(name, options={}, serializer_options={}) - @name = name + @name = name + @object = options[:value] + + @embed = options[:embed] + @embed_key = options[:embed_key] || :id + @embed_in_root = options[:include] + @options = options @serializer_options = serializer_options end - def name - options[:name] || @name - end - - def root - options[:root] || @name - end + attr_reader :root, :name, :embed_in_root + alias :embed_in_root? :embed_in_root def embed_ids? - [:id, :ids].include? options[:embed] + [:id, :ids].include? embed end def embed_objects? - [:object, :objects].include? options[:embed] - end - - def embed_in_root? - options[:include] + [:object, :objects].include? embed end def embeddable? @@ -34,17 +31,7 @@ module ActiveModel private - def object - options[:value] - end - - def embed_key - if key = options[:embed_key] - key - else - :id - end - end + attr_reader :object, :embed, :embed_key def target_serializer serializer = options[:serializer] @@ -75,6 +62,10 @@ module ActiveModel end end + def root + options[:root] || name + end + def id_key "#{@name.to_s.singularize}_ids".to_sym end From ecbb8bf6a663c7dcae2d1e8105fc8663c272054b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 16:14:27 -0700 Subject: [PATCH 27/38] Use == || == instead of include? --- lib/active_model/serializer/associations.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 0583d0c0..cacf7dbd 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -18,11 +18,11 @@ module ActiveModel alias :embed_in_root? :embed_in_root def embed_ids? - [:id, :ids].include? embed + embed == :id || embed == :ids end def embed_objects? - [:object, :objects].include? embed + embed == :object || embed == :objects end def embeddable? From 296970415a88476ed3a7db8e6c4306b9209a2bf7 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 17:12:02 -0700 Subject: [PATCH 28/38] Move key method to the base class --- lib/active_model/serializer/associations.rb | 35 +++++++++------------ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index cacf7dbd..4ef04176 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -17,9 +17,20 @@ module ActiveModel attr_reader :root, :name, :embed_in_root alias :embed_in_root? :embed_in_root + def key + if key = options[:key] + key + elsif use_id_key? + id_key + else + @name + end + end + def embed_ids? embed == :id || embed == :ids end + alias use_id_key? embed_ids? def embed_objects? embed == :object || embed == :objects @@ -52,16 +63,6 @@ module ActiveModel end class HasMany < Base #:nodoc: - def key - if key = options[:key] - key - elsif embed_ids? - id_key - else - @name - end - end - def root options[:root] || name end @@ -90,16 +91,6 @@ module ActiveModel end class HasOne < Base #:nodoc: - def key - if key = options[:key] - key - elsif embed_ids? && !polymorphic? - id_key - else - @name - end - end - def root if root = options[:root] root @@ -156,6 +147,10 @@ module ActiveModel private + def use_id_key? + embed_ids? && !polymorphic? + end + def polymorphic? options[:polymorphic] end From feaefeeef391be98d31005201976bcec5e597189 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 16:26:55 -0700 Subject: [PATCH 29/38] Use name reader --- lib/active_model/serializer/associations.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 4ef04176..6a73b386 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -23,7 +23,7 @@ module ActiveModel elsif use_id_key? id_key else - @name + name end end @@ -68,7 +68,7 @@ module ActiveModel end def id_key - "#{@name.to_s.singularize}_ids".to_sym + "#{name.to_s.singularize}_ids".to_sym end def serializables @@ -97,12 +97,12 @@ module ActiveModel elsif polymorphic? object.class.to_s.pluralize.demodulize.underscore.to_sym else - @name.to_s.pluralize.to_sym + name.to_s.pluralize.to_sym end end def id_key - "#{@name}_id".to_sym + "#{name}_id".to_sym end def embeddable? From 1c3f14407c5a670a8bc4bde5b30c6a8492654385 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 16:33:12 -0700 Subject: [PATCH 30/38] There's no need for target_serializer method --- lib/active_model/serializer/associations.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 6a73b386..cb652497 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -10,6 +10,9 @@ module ActiveModel @embed_key = options[:embed_key] || :id @embed_in_root = options[:include] + serializer = options[:serializer] + @serializer = serializer.is_a?(String) ? serializer.constantize : serializer + @options = options @serializer_options = serializer_options end @@ -42,16 +45,11 @@ module ActiveModel private - attr_reader :object, :embed, :embed_key - - def target_serializer - serializer = options[:serializer] - serializer.is_a?(String) ? serializer.constantize : serializer - end + attr_reader :object, :embed, :embed_key, :serializer def find_serializable(object) - if target_serializer - target_serializer.new(object, serializer_options) + if serializer + serializer.new(object, serializer_options) elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer) ams.new(object, serializer_options) else From cd9e1066404e4be2e93fb896c33a03326a7b4ff4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 17:26:38 -0700 Subject: [PATCH 31/38] All the attr_readers together --- lib/active_model/serializer/associations.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index cb652497..4b5324ca 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -45,7 +45,7 @@ module ActiveModel private - attr_reader :object, :embed, :embed_key, :serializer + attr_reader :object, :embed, :embed_key, :serializer, :options, :serializer_options def find_serializable(object) if serializer @@ -56,8 +56,6 @@ module ActiveModel object end end - - attr_reader :options, :serializer_options end class HasMany < Base #:nodoc: From e295af2e2b31e03f226a0968693881267a4f5ab6 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 17:27:25 -0700 Subject: [PATCH 32/38] Move embed methods to initialize and define readers --- lib/active_model/serializer/associations.rb | 22 +++++++++------------ 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 4b5324ca..7cfa3855 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -6,7 +6,9 @@ module ActiveModel @name = name @object = options[:value] - @embed = options[:embed] + embed = options[:embed] + @embed_ids = embed == :id || embed == :ids + @embed_objects = embed == :object || embed == :objects @embed_key = options[:embed_key] || :id @embed_in_root = options[:include] @@ -17,8 +19,11 @@ module ActiveModel @serializer_options = serializer_options end - attr_reader :root, :name, :embed_in_root - alias :embed_in_root? :embed_in_root + attr_reader :root, :name, :embed_ids, :embed_objects, :embed_in_root + alias embed_objects? embed_objects + alias embed_ids? embed_ids + alias use_id_key? embed_ids? + alias embed_in_root? embed_in_root def key if key = options[:key] @@ -30,22 +35,13 @@ module ActiveModel end end - def embed_ids? - embed == :id || embed == :ids - end - alias use_id_key? embed_ids? - - def embed_objects? - embed == :object || embed == :objects - end - def embeddable? !object.nil? end private - attr_reader :object, :embed, :embed_key, :serializer, :options, :serializer_options + attr_reader :object, :embed_key, :serializer, :options, :serializer_options def find_serializable(object) if serializer From bbd3c8b157db4f5ce7a3d24da40d67fd92511524 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 17:28:26 -0700 Subject: [PATCH 33/38] Define embeddable? as an alias of object --- lib/active_model/serializer/associations.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index 7cfa3855..aa77bf63 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -19,7 +19,8 @@ module ActiveModel @serializer_options = serializer_options end - attr_reader :root, :name, :embed_ids, :embed_objects, :embed_in_root + attr_reader :object, :root, :name, :embed_ids, :embed_objects, :embed_in_root + alias embeddable? object alias embed_objects? embed_objects alias embed_ids? embed_ids alias use_id_key? embed_ids? @@ -35,13 +36,9 @@ module ActiveModel end end - def embeddable? - !object.nil? - end - private - attr_reader :object, :embed_key, :serializer, :options, :serializer_options + attr_reader :embed_key, :serializer, :options, :serializer_options def find_serializable(object) if serializer From 36feb5d44fce75260759eb6e160c19d2b14d2f17 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 17:07:04 -0700 Subject: [PATCH 34/38] Refactor embeddable? method --- lib/active_model/serializer/associations.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index aa77bf63..e2e13c22 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -95,11 +95,7 @@ module ActiveModel end def embeddable? - if polymorphic? && object.nil? - false - else - true - end + super || !polymorphic? end def serializables From 0b6326eb352e363951a7911359569f38f35c35ec Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 17:10:04 -0700 Subject: [PATCH 35/38] Move polymorphic to initialize + reader --- lib/active_model/serializer/associations.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index e2e13c22..d647d816 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -80,6 +80,11 @@ module ActiveModel end class HasOne < Base #:nodoc: + def initialize(name, options={}, serializer_options={}) + super + @polymorphic = options[:polymorphic] + end + def root if root = options[:root] root @@ -132,14 +137,13 @@ module ActiveModel private + attr_reader :polymorphic + alias polymorphic? polymorphic + def use_id_key? embed_ids? && !polymorphic? end - def polymorphic? - options[:polymorphic] - end - def polymorphic_key object.class.to_s.demodulize.underscore.to_sym end From 787b7cf24a2096233c107548be1c67d8692f61b3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 15 May 2013 17:49:03 -0700 Subject: [PATCH 36/38] Document Associations --- lib/active_model/serializer/associations.rb | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index d647d816..cb3cb005 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -2,6 +2,28 @@ module ActiveModel class Serializer module Associations #:nodoc: class Base #:nodoc: + # name: The name of the association. + # + # options: A hash. These keys are accepted: + # + # value: The object we're associating with. + # + # serializer: The class used to serialize the association. + # + # embed: Define how associations should be embedded. + # - :objects # Embed associations as full objects. + # - :ids # Embed only the association ids. + # - :ids, :include => true # Embed the association ids and include objects in the root. + # + # include: Used in conjunction with embed :ids. Includes the objects in the root. + # + # root: Used in conjunction with include: true. Defines the key used to embed the objects. + # + # key: Key name used to store the ids in. + # + # embed_key: Method used to fetch ids. Defaults to :id. + # + # polymorphic: Is the association is polymorphic?. Values: true or false. def initialize(name, options={}, serializer_options={}) @name = name @object = options[:value] From 055f8fe33ca08a3ce23354428536bbd0dcfbb35c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 16:51:56 -0700 Subject: [PATCH 37/38] AMS::Associations::Base is now AMS::Association. HasMany and HasOne inherits from it. --- lib/active_model/serializer.rb | 8 +- lib/active_model/serializer/associations.rb | 132 ++++++++++---------- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 3468a09d..c4477fb1 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -152,7 +152,7 @@ module ActiveModel # with the association name does not exist, the association name is # dispatched to the serialized object. def has_many(*attrs) - associate(Associations::HasMany, attrs) + associate(Association::HasMany, attrs) end # Defines an association in the object should be rendered. @@ -162,7 +162,7 @@ module ActiveModel # with the association name does not exist, the association name is # dispatched to the serialized object. def has_one(*attrs) - associate(Associations::HasOne, attrs) + associate(Association::HasOne, attrs) end # Return a schema hash for the current serializer. This information @@ -372,9 +372,9 @@ module ActiveModel options = klass_options.merge options klass elsif value.respond_to?(:to_ary) - Associations::HasMany + Association::HasMany else - Associations::HasOne + Association::HasOne end options = default_embed_options.merge!(options) diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index cb3cb005..63760d41 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -1,79 +1,77 @@ module ActiveModel class Serializer - module Associations #:nodoc: - class Base #:nodoc: - # name: The name of the association. - # - # options: A hash. These keys are accepted: - # - # value: The object we're associating with. - # - # serializer: The class used to serialize the association. - # - # embed: Define how associations should be embedded. - # - :objects # Embed associations as full objects. - # - :ids # Embed only the association ids. - # - :ids, :include => true # Embed the association ids and include objects in the root. - # - # include: Used in conjunction with embed :ids. Includes the objects in the root. - # - # root: Used in conjunction with include: true. Defines the key used to embed the objects. - # - # key: Key name used to store the ids in. - # - # embed_key: Method used to fetch ids. Defaults to :id. - # - # polymorphic: Is the association is polymorphic?. Values: true or false. - def initialize(name, options={}, serializer_options={}) - @name = name - @object = options[:value] + class Association #:nodoc: + # name: The name of the association. + # + # options: A hash. These keys are accepted: + # + # value: The object we're associating with. + # + # serializer: The class used to serialize the association. + # + # embed: Define how associations should be embedded. + # - :objects # Embed associations as full objects. + # - :ids # Embed only the association ids. + # - :ids, :include => true # Embed the association ids and include objects in the root. + # + # include: Used in conjunction with embed :ids. Includes the objects in the root. + # + # root: Used in conjunction with include: true. Defines the key used to embed the objects. + # + # key: Key name used to store the ids in. + # + # embed_key: Method used to fetch ids. Defaults to :id. + # + # polymorphic: Is the association is polymorphic?. Values: true or false. + def initialize(name, options={}, serializer_options={}) + @name = name + @object = options[:value] - embed = options[:embed] - @embed_ids = embed == :id || embed == :ids - @embed_objects = embed == :object || embed == :objects - @embed_key = options[:embed_key] || :id - @embed_in_root = options[:include] + embed = options[:embed] + @embed_ids = embed == :id || embed == :ids + @embed_objects = embed == :object || embed == :objects + @embed_key = options[:embed_key] || :id + @embed_in_root = options[:include] - serializer = options[:serializer] - @serializer = serializer.is_a?(String) ? serializer.constantize : serializer + serializer = options[:serializer] + @serializer = serializer.is_a?(String) ? serializer.constantize : serializer - @options = options - @serializer_options = serializer_options - end + @options = options + @serializer_options = serializer_options + end - attr_reader :object, :root, :name, :embed_ids, :embed_objects, :embed_in_root - alias embeddable? object - alias embed_objects? embed_objects - alias embed_ids? embed_ids - alias use_id_key? embed_ids? - alias embed_in_root? embed_in_root + attr_reader :object, :root, :name, :embed_ids, :embed_objects, :embed_in_root + alias embeddable? object + alias embed_objects? embed_objects + alias embed_ids? embed_ids + alias use_id_key? embed_ids? + alias embed_in_root? embed_in_root - def key - if key = options[:key] - key - elsif use_id_key? - id_key - else - name - end - end - - private - - attr_reader :embed_key, :serializer, :options, :serializer_options - - def find_serializable(object) - if serializer - serializer.new(object, serializer_options) - elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer) - ams.new(object, serializer_options) - else - object - end + def key + if key = options[:key] + key + elsif use_id_key? + id_key + else + name end end - class HasMany < Base #:nodoc: + private + + attr_reader :embed_key, :serializer, :options, :serializer_options + + def find_serializable(object) + if serializer + serializer.new(object, serializer_options) + elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer) + ams.new(object, serializer_options) + else + object + end + end + + class HasMany < Association #:nodoc: def root options[:root] || name end @@ -101,7 +99,7 @@ module ActiveModel end end - class HasOne < Base #:nodoc: + class HasOne < Association #:nodoc: def initialize(name, options={}, serializer_options={}) super @polymorphic = options[:polymorphic] From 35608a85507232e112d135666e8c38703ed327c3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 16 May 2013 17:50:12 -0700 Subject: [PATCH 38/38] Move version.rb file to serializer directory --- active_model_serializers.gemspec | 2 +- lib/active_model/{serializers => serializer}/version.rb | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/active_model/{serializers => serializer}/version.rb (100%) diff --git a/active_model_serializers.gemspec b/active_model_serializers.gemspec index f4f90a81..0971a26e 100644 --- a/active_model_serializers.gemspec +++ b/active_model_serializers.gemspec @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- $:.unshift File.expand_path("../lib", __FILE__) -require "active_model/serializers/version" +require "active_model/serializer/version" Gem::Specification.new do |gem| gem.authors = ["José Valim", "Yehuda Katz"] diff --git a/lib/active_model/serializers/version.rb b/lib/active_model/serializer/version.rb similarity index 100% rename from lib/active_model/serializers/version.rb rename to lib/active_model/serializer/version.rb