mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
More refactoring:
* Changed associations to be classes * remove @hash and always use @options[:hash] * pass serializer options down to child serializers
This commit is contained in:
parent
89103f1e74
commit
b22eebf569
@ -11,13 +11,12 @@ module ActiveModel
|
|||||||
|
|
||||||
def initialize(object, scope, options={})
|
def initialize(object, scope, options={})
|
||||||
@object, @scope, @options = object, scope, options
|
@object, @scope, @options = object, scope, options
|
||||||
@hash = options[:hash]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def serializable_array
|
def serializable_array
|
||||||
@object.map do |item|
|
@object.map do |item|
|
||||||
if item.respond_to?(:active_model_serializer) && (serializer = item.active_model_serializer)
|
if item.respond_to?(:active_model_serializer) && (serializer = item.active_model_serializer)
|
||||||
serializer.new(item, scope, :hash => @hash)
|
serializer.new(item, scope, @options)
|
||||||
else
|
else
|
||||||
item
|
item
|
||||||
end
|
end
|
||||||
@ -25,12 +24,12 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def as_json(*args)
|
def as_json(*args)
|
||||||
@hash = {}
|
@options[:hash] = hash = {}
|
||||||
|
|
||||||
array = serializable_array.map(&:serializable_hash)
|
array = serializable_array.map(&:serializable_hash)
|
||||||
|
|
||||||
if root = @options[:root]
|
if root = @options[:root]
|
||||||
@hash.merge!(root => array)
|
hash.merge!(root => array)
|
||||||
else
|
else
|
||||||
array
|
array
|
||||||
end
|
end
|
||||||
@ -71,32 +70,71 @@ module ActiveModel
|
|||||||
#
|
#
|
||||||
class Serializer
|
class Serializer
|
||||||
module Associations #:nodoc:
|
module Associations #:nodoc:
|
||||||
class Config < Struct.new(:name, :options) #:nodoc:
|
class Config #:nodoc:
|
||||||
def serializer
|
class_attribute :association_name
|
||||||
options[:serializer]
|
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.association_name = name
|
||||||
|
self.options = class_options
|
||||||
|
|
||||||
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||||
|
def initialize(options={})
|
||||||
|
super(self.class.association_name, options)
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.options = {}
|
||||||
|
|
||||||
|
def initialize(name=nil, options={})
|
||||||
|
@name = name || self.class.association_name
|
||||||
|
@options = options
|
||||||
|
end
|
||||||
|
|
||||||
|
def option(key)
|
||||||
|
if @options.key?(key)
|
||||||
|
@options[key]
|
||||||
|
elsif self.class.options[key]
|
||||||
|
self.class.options[key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def target_serializer
|
||||||
|
option(:serializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
def key
|
def key
|
||||||
options[:key] || name
|
option(:key) || @name
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
option(:name) || @name
|
||||||
end
|
end
|
||||||
|
|
||||||
def associated_object(serializer)
|
def associated_object(serializer)
|
||||||
options[:value] || serializer.send(name)
|
option(:value) || serializer.send(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_options(options)
|
protected
|
||||||
config = dup
|
|
||||||
config.options.merge!(options)
|
|
||||||
config
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
def find_serializable(object, scope, serializer)
|
||||||
|
if target_serializer
|
||||||
def find_serializable(object, scope, context, options)
|
target_serializer.new(object, scope, serializer.options)
|
||||||
if serializer
|
|
||||||
serializer.new(object, scope, options)
|
|
||||||
elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer)
|
elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer)
|
||||||
ams.new(object, scope, options)
|
ams.new(object, scope, serializer.options)
|
||||||
else
|
else
|
||||||
object
|
object
|
||||||
end
|
end
|
||||||
@ -108,7 +146,7 @@ module ActiveModel
|
|||||||
|
|
||||||
def serialize(serializer, scope)
|
def serialize(serializer, scope)
|
||||||
associated_object(serializer).map do |item|
|
associated_object(serializer).map do |item|
|
||||||
find_serializable(item, scope, serializer, options).as_json(:root => false)
|
find_serializable(item, scope, serializer).serializable_hash
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias serialize_many serialize
|
alias serialize_many serialize
|
||||||
@ -130,12 +168,12 @@ module ActiveModel
|
|||||||
|
|
||||||
def serialize(serializer, scope)
|
def serialize(serializer, scope)
|
||||||
object = associated_object(serializer)
|
object = associated_object(serializer)
|
||||||
object && find_serializable(object, scope, serializer, options).as_json(:root => false)
|
object && find_serializable(object, scope, serializer).serializable_hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialize_many(serializer, scope)
|
def serialize_many(serializer, scope)
|
||||||
object = associated_object(serializer)
|
object = associated_object(serializer)
|
||||||
value = object && find_serializable(object, scope, serializer, options).as_json(:root => false)
|
value = object && find_serializable(object, scope, serializer).serializable_hash
|
||||||
value ? [value] : []
|
value ? [value] : []
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -180,7 +218,8 @@ module ActiveModel
|
|||||||
unless method_defined?(attr)
|
unless method_defined?(attr)
|
||||||
class_eval "def #{attr}() object.#{attr} end", __FILE__, __LINE__
|
class_eval "def #{attr}() object.#{attr} end", __FILE__, __LINE__
|
||||||
end
|
end
|
||||||
klass.new(attr, options)
|
|
||||||
|
klass.refine(attr, options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -245,7 +284,9 @@ module ActiveModel
|
|||||||
hash.merge key => column.type
|
hash.merge key => column.type
|
||||||
end
|
end
|
||||||
|
|
||||||
associations = _associations.inject({}) do |hash, association|
|
associations = _associations.inject({}) do |hash, association_class|
|
||||||
|
association = association_class.new
|
||||||
|
|
||||||
model_association = klass.reflect_on_association(association.name)
|
model_association = klass.reflect_on_association(association.name)
|
||||||
hash.merge association.key => { model_association.macro => model_association.name }
|
hash.merge association.key => { model_association.macro => model_association.name }
|
||||||
end
|
end
|
||||||
@ -285,11 +326,10 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :object, :scope
|
attr_reader :object, :scope, :options
|
||||||
|
|
||||||
def initialize(object, scope, options={})
|
def initialize(object, scope, options={})
|
||||||
@object, @scope, @options = object, scope, options
|
@object, @scope, @options = object, scope, options
|
||||||
@hash = options[:hash]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a json representation of the serializable
|
# Returns a json representation of the serializable
|
||||||
@ -297,11 +337,11 @@ module ActiveModel
|
|||||||
def as_json(options=nil)
|
def as_json(options=nil)
|
||||||
options ||= {}
|
options ||= {}
|
||||||
if root = options.fetch(:root, @options.fetch(:root, _root))
|
if root = options.fetch(:root, @options.fetch(:root, _root))
|
||||||
@hash = hash = {}
|
@options[:hash] = hash = {}
|
||||||
hash.merge!(root => serializable_hash)
|
hash.merge!(root => serializable_hash)
|
||||||
hash
|
hash
|
||||||
else
|
else
|
||||||
@hash = serializable_hash
|
serializable_hash
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -309,7 +349,7 @@ module ActiveModel
|
|||||||
# object without the root.
|
# object without the root.
|
||||||
def serializable_hash
|
def serializable_hash
|
||||||
if _embed == :ids
|
if _embed == :ids
|
||||||
merge_associations(@hash, plural_associations) if _root_embed
|
merge_associations(@options[:hash], plural_associations) if _root_embed
|
||||||
attributes.merge(association_ids)
|
attributes.merge(association_ids)
|
||||||
elsif _embed == :objects
|
elsif _embed == :objects
|
||||||
attributes.merge(associations)
|
attributes.merge(associations)
|
||||||
@ -327,11 +367,11 @@ module ActiveModel
|
|||||||
serializer = options[:serializer]
|
serializer = options[:serializer]
|
||||||
scope = options[:scope]
|
scope = options[:scope]
|
||||||
|
|
||||||
association = _associations.find do |a|
|
association_class = _associations.find do |a|
|
||||||
a.name == name
|
a.association_name == name
|
||||||
end
|
end
|
||||||
|
|
||||||
association = association.with_options(options) if association
|
association = association_class.new(options) if association_class
|
||||||
|
|
||||||
association ||= if value.respond_to?(:to_ary)
|
association ||= if value.respond_to?(:to_ary)
|
||||||
Associations::HasMany.new(name, options)
|
Associations::HasMany.new(name, options)
|
||||||
@ -371,8 +411,8 @@ module ActiveModel
|
|||||||
def associations
|
def associations
|
||||||
hash = {}
|
hash = {}
|
||||||
|
|
||||||
_associations.each do |association|
|
_associations.each do |association_class|
|
||||||
association = association.with_options(:hash => @hash)
|
association = association_class.new
|
||||||
hash[association.key] = association.serialize(self, scope)
|
hash[association.key] = association.serialize(self, scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -382,8 +422,8 @@ module ActiveModel
|
|||||||
def plural_associations
|
def plural_associations
|
||||||
hash = {}
|
hash = {}
|
||||||
|
|
||||||
_associations.each do |association|
|
_associations.each do |association_class|
|
||||||
association = association.with_options(:hash => @hash)
|
association = association_class.new
|
||||||
hash[association.plural_key] = association.serialize_many(self, scope)
|
hash[association.plural_key] = association.serialize_many(self, scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -395,7 +435,8 @@ module ActiveModel
|
|||||||
def association_ids
|
def association_ids
|
||||||
hash = {}
|
hash = {}
|
||||||
|
|
||||||
_associations.each do |association|
|
_associations.each do |association_class|
|
||||||
|
association = association_class.new
|
||||||
hash[association.key] = association.serialize_ids(self, scope)
|
hash[association.key] = association.serialize_ids(self, scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -737,7 +737,7 @@ class SerializerTest < ActiveModel::TestCase
|
|||||||
attributes :id, :name
|
attributes :id, :name
|
||||||
|
|
||||||
define_method :serializable_hash do
|
define_method :serializable_hash do
|
||||||
hash_object = @hash
|
hash_object = @options[:hash]
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user