Skip to content

Commit

Permalink
Add initial support for embed API
Browse files Browse the repository at this point in the history
  • Loading branch information
wycats committed Oct 15, 2011
1 parent a230f04 commit 2abb2e6
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 7 deletions.
22 changes: 19 additions & 3 deletions activemodel/lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def serialize(collection, scope)

def serialize_ids(collection, scope)
# use named scopes if they are present
return collection.ids if collection.respond_to?(:ids)
#return collection.ids if collection.respond_to?(:ids)

collection.map do |item|
item.read_attribute_for_serialization(:id)
Expand All @@ -47,6 +47,9 @@ def serialize_ids(object, scope)
self._associations = []

class_attribute :_root
class_attribute :_embed
self._embed = :objects
class_attribute :_root_embed

class << self
def attributes(*attrs)
Expand All @@ -73,6 +76,11 @@ def has_one(*attrs)
associate(Associations::HasOne, attrs)
end

def embed(type, options={})
self._embed = type
self._root_embed = true if options[:include]
end

def root(name)
self._root = name
end
Expand All @@ -97,14 +105,22 @@ def initialize(object, scope)

def as_json(*)
if _root
{ _root => serializable_hash }
hash = { _root => serializable_hash }
hash.merge!(associations) if _root_embed
hash
else
serializable_hash
end
end

def serializable_hash
attributes.merge(associations)
if _embed == :ids
attributes.merge(association_ids)
elsif _embed == :objects
attributes.merge(associations)
else
attributes
end
end

def associations
Expand Down
86 changes: 82 additions & 4 deletions activemodel/test/cases/serializer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,12 @@ def post_serializer(type)
attributes :title, :body
has_many :comments, :serializer => CommentSerializer

define_method :serializable_hash do
post_hash = attributes
post_hash.merge!(send(type))
post_hash
if type != :super
define_method :serializable_hash do
post_hash = attributes
post_hash.merge!(send(type))
post_hash
end
end
end
end
Expand Down Expand Up @@ -325,4 +327,80 @@ def test_false_root
serializer = Class.new(serializer)
assert_equal({ :author => nil }, serializer.new(blog, user).as_json)
end

def test_embed_ids
serializer = post_serializer(:super)

serializer.class_eval do
root :post
embed :ids
end

post = Post.new(:title => "New Post", :body => "Body of new post", :email => "[email protected]")
comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
post.comments = comments

serializer = serializer.new(post, nil)

assert_equal({
:post => {
:title => "New Post",
:body => "Body of new post",
:comments => [1, 2]
}
}, serializer.as_json)
end

def test_embed_ids_include_true
serializer = post_serializer(:super)

serializer.class_eval do
root :post
embed :ids, :include => true
end

post = Post.new(:title => "New Post", :body => "Body of new post", :email => "[email protected]")
comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
post.comments = comments

serializer = serializer.new(post, nil)

assert_equal({
:post => {
:title => "New Post",
:body => "Body of new post",
:comments => [1, 2]
},
:comments => [
{ :title => "Comment1" },
{ :title => "Comment2" }
]
}, serializer.as_json)
end

def test_embed_objects
serializer = post_serializer(:super)

serializer.class_eval do
root :post
embed :objects
end

post = Post.new(:title => "New Post", :body => "Body of new post", :email => "[email protected]")
comments = [Comment.new(:title => "Comment1", :id => 1), Comment.new(:title => "Comment2", :id => 2)]
post.comments = comments

serializer = serializer.new(post, nil)

assert_equal({
:post => {
:title => "New Post",
:body => "Body of new post",
:comments => [
{ :title => "Comment1" },
{ :title => "Comment2" }
]
}
}, serializer.as_json)
end
end

0 comments on commit 2abb2e6

Please sign in to comment.