Embed objects should return singular and not wrap in array

Closes #437
This commit is contained in:
Santiago Pastorino 2013-11-01 14:22:48 -02:00
parent 78cceb4113
commit 66f9256534
4 changed files with 25 additions and 20 deletions

View File

@ -131,7 +131,8 @@ end
if association.embed_ids? if association.embed_ids?
hash[association.key] = serialize_ids association hash[association.key] = serialize_ids association
elsif association.embed_objects? elsif association.embed_objects?
hash[association.embedded_key] = serialize association associated_data = send(association.name)
hash[association.embedded_key] = serialize(association, associated_data)
end end
end end
end end
@ -147,15 +148,15 @@ end
associations.each_with_object({}) do |(name, association), hash| associations.each_with_object({}) do |(name, association), hash|
if included_associations.include? name if included_associations.include? name
if association.embed_in_root? if association.embed_in_root?
hash[association.embedded_key] = serialize association associated_data = Array(send(association.name))
hash[association.root_key] = serialize(association, associated_data)
end end
end end
end end
end end
def serialize(association) def serialize(association, object)
associated_data = send(association.name) association.build_serializer(object).serializable_object
association.build_serializer(associated_data).serializable_object
end end
def serialize_ids(association) def serialize_ids(association)

View File

@ -17,24 +17,22 @@ module ActiveModel
@embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } } @embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } }
@embed_key = options[:embed_key] || :id @embed_key = options[:embed_key] || :id
@key = options[:key] @key = options[:key]
@embedded_key = options[:root] || name
self.serializer_class = @options[:serializer] self.serializer_class = @options[:serializer]
end end
attr_reader :name, :embed_ids, :embed_objects, :serializer_class attr_reader :name, :embed_ids, :embed_objects, :serializer_class
attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, :options attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, :root_key, :options
alias embed_ids? embed_ids alias embed_ids? embed_ids
alias embed_objects? embed_objects alias embed_objects? embed_objects
alias embed_in_root? embed_in_root alias embed_in_root? embed_in_root
def serializer_class=(serializer) def serializer_class=(serializer)
@serializer_class = serializer.is_a?(String) ? serializer.constantize : serializer @serializer_class = serializer.is_a?(String) ? serializer.constantize : serializer
if @serializer_class && !(@serializer_class <= ArraySerializer) if @serializer_class && !(@serializer_class <= ArraySerializer)
@options.merge!(each_serializer: @serializer_class) @options.merge!(each_serializer: @serializer_class)
@serializer_class = ArraySerializer @serializer_class = ArraySerializer
else
@serializer_class ||= ArraySerializer
end end
end end
@ -43,24 +41,30 @@ module ActiveModel
@embed_objects = embed == :object || embed == :objects @embed_objects = embed == :object || embed == :objects
end end
def build_serializer(object)
@serializer_class.new(Array(object), @options)
end
class HasOne < Association class HasOne < Association
def initialize(name, *args) def initialize(name, *args)
super super
@embedded_key = "#{@options[:root] || name}".pluralize @root_key = @embedded_key.to_s.pluralize
@key ||= "#{name}_id" @key ||= "#{name}_id"
end end
def build_serializer(object)
@serializer_class ||= Serializer.serializer_for(object) || DefaultSerializer
@serializer_class.new(object, @options)
end
end end
class HasMany < Association class HasMany < Association
def initialize(name, *args) def initialize(name, *args)
super super
@embedded_key = @options[:root] || name @root_key = @embedded_key
@key ||= "#{name.to_s.singularize}_ids" @key ||= "#{name.to_s.singularize}_ids"
end end
def build_serializer(object)
@serializer_class ||= ArraySerializer
@serializer_class.new(object, @options)
end
end end
end end
end end

View File

@ -17,7 +17,7 @@ module ActiveModel
ar_comments: [{ body: 'what a dumb post', ar_tags: [{ name: 'short' }, { name: 'whiny' }] }, ar_comments: [{ body: 'what a dumb post', ar_tags: [{ name: 'short' }, { name: 'whiny' }] },
{ body: 'i liked it', ar_tags: [{:name=>"short"}, {:name=>"happy"}] }], { body: 'i liked it', ar_tags: [{:name=>"short"}, {:name=>"happy"}] }],
ar_tags: [{ name: 'short' }, { name: 'whiny' }, { name: 'happy' }], ar_tags: [{ name: 'short' }, { name: 'whiny' }, { name: 'happy' }],
'ar_sections' => [{ 'name' => 'ruby' }] ar_section: { 'name' => 'ruby' }
} }
}, post_serializer.as_json) }, post_serializer.as_json)
end end

View File

@ -50,7 +50,7 @@ module ActiveModel
@association.embed = :objects @association.embed = :objects
assert_equal({ assert_equal({
name: 'Name 1', email: 'mail@server.com', 'profiles' => [{ name: 'N1', description: 'D1' }] name: 'Name 1', email: 'mail@server.com', profile: { name: 'N1', description: 'D1' }
}, @user_serializer.serializable_hash) }, @user_serializer.serializable_hash)
end end
@ -58,7 +58,7 @@ module ActiveModel
@association.embed = :objects @association.embed = :objects
assert_equal({ assert_equal({
'user' => { name: 'Name 1', email: 'mail@server.com', 'profiles' => [{ name: 'N1', description: 'D1' }] } 'user' => { name: 'Name 1', email: 'mail@server.com', profile: { name: 'N1', description: 'D1' } }
}, @user_serializer.as_json) }, @user_serializer.as_json)
end end
@ -84,7 +84,7 @@ module ActiveModel
end end
assert_equal({ assert_equal({
'user' => { name: 'Name 1', email: 'mail@server.com', 'profiles' => [] } 'user' => { name: 'Name 1', email: 'mail@server.com', profile: nil }
}, @user_serializer.as_json) }, @user_serializer.as_json)
end end
@ -93,7 +93,7 @@ module ActiveModel
@association.embedded_key = 'root' @association.embedded_key = 'root'
assert_equal({ assert_equal({
name: 'Name 1', email: 'mail@server.com', 'root' => [{ name: 'N1', description: 'D1' }] name: 'Name 1', email: 'mail@server.com', 'root' => { name: 'N1', description: 'D1' }
}, @user_serializer.serializable_hash) }, @user_serializer.serializable_hash)
end end