Permalink
Browse files

Merge pull request #43 from ctide/master

Add a :root option when defining associations
  • Loading branch information...
2 parents 2f6d1e2 + f17e4cd commit 5f0bb6d1481478f8aea2111cc14ea286be0bfc95 @josevalim josevalim committed Feb 23, 2012
Showing with 78 additions and 1 deletion.
  1. +24 −0 README.markdown
  2. +5 −1 lib/active_model/serializer.rb
  3. +49 −0 test/serializer_test.rb
View
@@ -163,6 +163,30 @@ Assuming that the comments also `has_many :tags`, you will get a JSON like this:
{ "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.
@@ -146,6 +146,10 @@ def key
option(:key) || @name
end
+ def root
+ option(:root) || plural_key
+ end
+
def name
option(:name) || @name
end
@@ -454,7 +458,7 @@ def include!(name, options={})
node[association.key] = association.serialize_ids
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
elsif association.embed_objects?
node[association.key] = association.serialize
@@ -702,7 +702,56 @@ def test_serializer_has_access_to_root_object
expected = serializer_class.new(post).as_json
assert_equal expected, hash_object
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
# still side-load at the root.
def test_embed_with_include_inserts_at_root

0 comments on commit 5f0bb6d

Please sign in to comment.