Skip to content

Commit

Permalink
Merge pull request rails-api#43 from ctide/master
Browse files Browse the repository at this point in the history
Add a :root option when defining associations
  • Loading branch information
josevalim committed Feb 23, 2012
2 parents 2f6d1e2 + f17e4cd commit 5f0bb6d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
24 changes: 24 additions & 0 deletions README.markdown
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -163,6 +163,30 @@ Assuming that the comments also `has_many :tags`, you will get a JSON like this:
{ "id": 3, "name": "happy" } { "id": 3, "name": "happy" }
] ]
} }

You can also specify a different root for the embedded objects than the key used to reference them, such as like this:

class PostSerializer < ApplicationSerializer
embed :ids, :include => true

attributes :id, :title, :body
has_many :comments, :key => :comment_ids, :root => :comment_objects
end

This would generate JSON that would look like this:

{
"post": {
"id": 1,
"title": "New post",
"body": "A body!",
"comment_ids": [ 1 ]
},
"comment_objects": [
{ "id": 1, "body": "what a dumb post" }
]
}



**NOTE**: The `embed :ids` mechanism is primary useful for clients that process data in bulk and load it into a local store. For these clients, the ability to easily see all of the data per type, rather than having to recursively scan the data looking for information, is extremely useful. **NOTE**: The `embed :ids` mechanism is primary useful for clients that process data in bulk and load it into a local store. For these clients, the ability to easily see all of the data per type, rather than having to recursively scan the data looking for information, is extremely useful.


Expand Down
6 changes: 5 additions & 1 deletion lib/active_model/serializer.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ def key
option(:key) || @name option(:key) || @name
end end


def root
option(:root) || plural_key
end

def name def name
option(:name) || @name option(:name) || @name
end end
Expand Down Expand Up @@ -454,7 +458,7 @@ def include!(name, options={})
node[association.key] = association.serialize_ids node[association.key] = association.serialize_ids


if association.embed_in_root? if association.embed_in_root?
merge_association hash, association.plural_key, association.serialize_many, unique_values merge_association hash, association.root, association.serialize_many, unique_values
end end
elsif association.embed_objects? elsif association.embed_objects?
node[association.key] = association.serialize node[association.key] = association.serialize
Expand Down
49 changes: 49 additions & 0 deletions test/serializer_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -702,7 +702,56 @@ def test_serializer_has_access_to_root_object
expected = serializer_class.new(post).as_json expected = serializer_class.new(post).as_json
assert_equal expected, hash_object assert_equal expected, hash_object
end end

def test_embed_ids_include_true_with_root
serializer_class = post_serializer

serializer_class.class_eval do
root :post
embed :ids, :include => true
has_many :comments, :key => :comment_ids, :root => :comments
has_one :author, :serializer => DefaultUserSerializer, :key => :author_id, :root => :author
end

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

serializer = serializer_class.new(post)

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

post.author = User.new(:id => 1)

serializer = serializer_class.new(post)


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

# the point of this test is to illustrate that deeply nested serializers # the point of this test is to illustrate that deeply nested serializers
# still side-load at the root. # still side-load at the root.
def test_embed_with_include_inserts_at_root def test_embed_with_include_inserts_at_root
Expand Down

0 comments on commit 5f0bb6d

Please sign in to comment.