Skip to content

Commit

Permalink
Merge pull request rails-api#792 from rails-api/association-overrides
Browse files Browse the repository at this point in the history
Association overrides
  • Loading branch information
guilleiguaran committed Jan 30, 2015
2 parents ba1905a + e771e63 commit 4264454
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
### 0.10.0

* adds support for `meta` and `meta_key` [@kurko]
* adds method to override association [adcb99e, @kurko]
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,22 @@ call:
render json: @post, root: "articles"
```

### Overriding association methods

If you want to override any association, you can use:

```ruby
class PostSerializer < ActiveModel::Serializer
attributes :id, :body

has_many :comments

def comments
object.comments.active
end
end
```

### Built in Adapters

#### JSONAPI
Expand Down
4 changes: 3 additions & 1 deletion lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,12 @@ def attributes(options = {})
def each_association(&block)
self.class._associations.dup.each do |name, options|
next unless object

association = object.send(name)
association_value = send(name)
serializer_class = ActiveModel::Serializer.serializer_for(association, options)
serializer = serializer_class.new(
association,
association_value,
serializer_from_options(options)
) if serializer_class

Expand Down
3 changes: 3 additions & 0 deletions test/action_controller/json_api_linked_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def setup_post
@post2 = Post.new(id: 2, title: "Another Post", body: "Body")
@post2.author = @author
@post2.comments = []
@blog = Blog.new(id: 1, name: "My Blog!!")
@post.blog = @blog
@post2.blog = @blog
end

def render_resource_without_include
Expand Down
5 changes: 4 additions & 1 deletion test/adapter/json/belongs_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def setup
@comment.post = @post
@comment.author = nil
@anonymous_post.author = nil
@blog = Blog.new(id: 1, name: "My Blog!!")
@post.blog = @blog
@anonymous_post.blog = nil

@serializer = CommentSerializer.new(@comment)
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
Expand All @@ -28,7 +31,7 @@ def test_include_nil_author
serializer = PostSerializer.new(@anonymous_post)
adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)

assert_equal({title: "Hello!!", body: "Hello, world!!", id: 43, comments: [], author: nil}, adapter.serializable_hash)
assert_equal({title: "Hello!!", body: "Hello, world!!", id: 43, comments: [], blog: nil, author: nil}, adapter.serializable_hash)
end
end
end
Expand Down
32 changes: 28 additions & 4 deletions test/adapter/json/collection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,40 @@ def setup
@second_post.comments = []
@first_post.author = @author
@second_post.author = @author
@blog = Blog.new(id: 1, name: "My Blog!!")
@first_post.blog = @blog
@second_post.blog = nil

@serializer = ArraySerializer.new([@first_post, @second_post])
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
end

def test_include_multiple_posts
assert_equal([
{title: "Hello!!", body: "Hello, world!!", id: 1, comments: [], author: {id: 1, name: "Steve K."}},
{title: "New Post", body: "Body", id: 2, comments: [], author: {id: 1, name: "Steve K."}}
], @adapter.serializable_hash)
expected = [{
title: "Hello!!",
body: "Hello, world!!",
id: 1,
comments: [],
author: {
id: 1,
name: "Steve K."
},
blog: {
id: 999,
name: "Custom blog"
}
}, {
title: "New Post",
body: "Body",
id: 2,
comments: [],
author: {
id: 1,
name: "Steve K."
},
blog: nil
}]
assert_equal expected, @adapter.serializable_hash
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions test/adapter/json/has_many_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def setup
@post.author = @author
@first_comment.post = @post
@second_comment.post = @post
@blog = Blog.new(id: 1, name: "My Blog!!")
@post.blog = @blog

@serializer = PostSerializer.new(@post)
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
Expand Down
9 changes: 8 additions & 1 deletion test/adapter/json_api/belongs_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ def setup
@author = Author.new(id: 1, name: 'Steve K.')
@author.bio = nil
@author.roles = []
@blog = Blog.new(id: 23, name: 'AMS Blog')
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
@post.comments = [@comment]
@post.blog = @blog
@anonymous_post.comments = []
@anonymous_post.blog = nil
@comment.post = @post
@comment.author = nil
@post.author = @author
Expand All @@ -39,6 +42,7 @@ def test_includes_linked_post
body: 'Body',
links: {
comments: ["1"],
blog: "999",
author: "1"
}
}]
Expand All @@ -51,6 +55,7 @@ def test_limiting_linked_post_fields
title: 'New Post',
links: {
comments: ["1"],
blog: "999",
author: "1"
}
}]
Expand All @@ -61,7 +66,7 @@ def test_include_nil_author
serializer = PostSerializer.new(@anonymous_post)
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)

assert_equal({comments: [], author: nil}, adapter.serializable_hash[:posts][:links])
assert_equal({comments: [], blog: nil, author: nil}, adapter.serializable_hash[:posts][:links])
end

def test_include_type_for_association_when_different_than_name
Expand Down Expand Up @@ -101,6 +106,7 @@ def test_include_linked_resources_with_type_name
id: "42",
links: {
comments: ["1"],
blog: "999",
author: "1"
}
}, {
Expand All @@ -109,6 +115,7 @@ def test_include_linked_resources_with_type_name
id: "43",
links: {
comments: [],
blog: nil,
author: nil
}
}]
Expand Down
11 changes: 7 additions & 4 deletions test/adapter/json_api/collection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ class CollectionTest < Minitest::Test
def setup
@author = Author.new(id: 1, name: 'Steve K.')
@author.bio = nil
@blog = Blog.new(id: 23, name: 'AMS Blog')
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
@first_post.comments = []
@second_post.comments = []
@first_post.blog = @blog
@second_post.blog = nil
@first_post.author = @author
@second_post.author = @author
@author.posts = [@first_post, @second_post]
Expand All @@ -22,16 +25,16 @@ def setup

def test_include_multiple_posts
assert_equal([
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: [], author: "1" } },
{ title: "New Post", body: "Body", id: "2", links: { comments: [], author: "1" } }
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: [], blog: "999", author: "1" } },
{ title: "New Post", body: "Body", id: "2", links: { comments: [], blog: nil, author: "1" } }
], @adapter.serializable_hash[:posts])
end

def test_limiting_fields
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, fields: ['title'])
assert_equal([
{ title: "Hello!!", links: { comments: [], author: "1" } },
{ title: "New Post", links: { comments: [], author: "1" } }
{ title: "Hello!!", links: { comments: [], blog: "999", author: "1" } },
{ title: "New Post", links: { comments: [], blog: nil, author: "1" } }
], @adapter.serializable_hash[:posts])
end

Expand Down
3 changes: 3 additions & 0 deletions test/adapter/json_api/has_many_embed_ids_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ def setup
@second_post.author = @author
@first_post.comments = []
@second_post.comments = []
@blog = Blog.new(id: 23, name: 'AMS Blog')
@first_post.blog = @blog
@second_post.blog = nil

@serializer = AuthorSerializer.new(@author)
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
Expand Down
2 changes: 2 additions & 0 deletions test/adapter/json_api/has_many_explicit_serializer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def setup
@first_comment.author = nil
@second_comment.post = @post
@second_comment.author = nil
@blog = Blog.new(id: 23, name: 'AMS Blog')
@post.blog = @blog

@serializer = PostPreviewSerializer.new(@post)
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
Expand Down
4 changes: 3 additions & 1 deletion test/adapter/json_api/has_many_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ def setup
@blog = Blog.new(id: 1, name: "My Blog!!")
@blog.writer = @author
@blog.articles = [@post]
@post.blog = @blog
@post_without_comments.blog = nil

@serializer = PostSerializer.new(@post)
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
Expand All @@ -32,7 +34,7 @@ def setup
def test_includes_comment_ids
assert_equal(["1", "2"], @adapter.serializable_hash[:posts][:links][:comments])
end

def test_includes_linked_comments
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments')
expected = [{
Expand Down
6 changes: 6 additions & 0 deletions test/adapter/json_api/linked_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ def setup
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
@third_post = Post.new(id: 3, title: 'Yet Another Post', body: 'Body')
@blog = Blog.new({ name: 'AMS Blog' })
@first_post.blog = @blog
@second_post.blog = @blog
@third_post.blog = nil
@first_post.comments = []
@second_post.comments = []
@first_post.author = @author1
Expand Down Expand Up @@ -124,6 +128,7 @@ def test_include_multiple_posts_and_linked
id: "1",
links: {
comments: ["1", "2"],
blog: "999",
author: "1"
}
}, {
Expand All @@ -132,6 +137,7 @@ def test_include_multiple_posts_and_linked
id: "3",
links: {
comments: [],
blog: nil,
author: "1"
}
}]
Expand Down
2 changes: 2 additions & 0 deletions test/adapter/json_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def setup
@first_comment.post = @post
@second_comment.post = @post
@post.author = @author
@blog = Blog.new(id: 1, name: "My Blog!!")
@post.blog = @blog

@serializer = PostSerializer.new(@post)
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/poro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,13 @@ module Spam; end
attributes :title, :body, :id

has_many :comments
belongs_to :blog
belongs_to :author
url :comments

def blog
Blog.new(id: 999, name: "Custom blog")
end
end

SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
Expand Down
15 changes: 14 additions & 1 deletion test/serializers/associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ def setup
@author = Author.new(name: 'Steve K.')
@author.bio = nil
@author.roles = []
@blog = Blog.new({ name: 'AMS Blog' })
@post = Post.new({ title: 'New Post', body: 'Body' })
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
@post.comments = [@comment]
@post.blog = @blog
@comment.post = @post
@comment.author = nil
@post.author = @author
@author.posts = [@post]

@post_serializer = PostSerializer.new(@post)
@author_serializer = AuthorSerializer.new(@author)
@comment_serializer = CommentSerializer.new(@comment)
end
Expand Down Expand Up @@ -63,7 +66,7 @@ def test_has_many
end
end

def test_has_one
def test_belongs_to
assert_equal({post: {type: :belongs_to, association_options: {}}, :author=>{:type=>:belongs_to, :association_options=>{}}}, @comment_serializer.class._associations)
@comment_serializer.each_association do |name, serializer, options|
if name == :post
Expand All @@ -77,6 +80,16 @@ def test_has_one
end
end
end

def test_belongs_to_with_custom_method
blog_is_present = false

@post_serializer.each_association do |name, serializer, options|
blog_is_present = true if name == :blog
end

assert blog_is_present
end
end
end
end

0 comments on commit 4264454

Please sign in to comment.