mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
Support overriding association methods
You can override associations to define custom scope on them.
This commit is contained in:
parent
652493848a
commit
e47231cdc8
16
README.md
16
README.md
@ -146,6 +146,22 @@ call:
|
|||||||
render json: @post, root: "articles"
|
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
|
### Built in Adapters
|
||||||
|
|
||||||
#### JSONAPI
|
#### JSONAPI
|
||||||
|
|||||||
@ -149,10 +149,12 @@ module ActiveModel
|
|||||||
def each_association(&block)
|
def each_association(&block)
|
||||||
self.class._associations.dup.each do |name, options|
|
self.class._associations.dup.each do |name, options|
|
||||||
next unless object
|
next unless object
|
||||||
|
|
||||||
association = object.send(name)
|
association = object.send(name)
|
||||||
|
association_value = send(name)
|
||||||
serializer_class = ActiveModel::Serializer.serializer_for(association, options)
|
serializer_class = ActiveModel::Serializer.serializer_for(association, options)
|
||||||
serializer = serializer_class.new(
|
serializer = serializer_class.new(
|
||||||
association,
|
association_value,
|
||||||
serializer_from_options(options)
|
serializer_from_options(options)
|
||||||
) if serializer_class
|
) if serializer_class
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,9 @@ module ActionController
|
|||||||
@post2 = Post.new(id: 2, title: "Another Post", body: "Body")
|
@post2 = Post.new(id: 2, title: "Another Post", body: "Body")
|
||||||
@post2.author = @author
|
@post2.author = @author
|
||||||
@post2.comments = []
|
@post2.comments = []
|
||||||
|
@blog = Blog.new(id: 1, name: "My Blog!!")
|
||||||
|
@post.blog = @blog
|
||||||
|
@post2.blog = @blog
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_resource_without_include
|
def render_resource_without_include
|
||||||
|
|||||||
@ -15,6 +15,9 @@ module ActiveModel
|
|||||||
@comment.post = @post
|
@comment.post = @post
|
||||||
@comment.author = nil
|
@comment.author = nil
|
||||||
@anonymous_post.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)
|
@serializer = CommentSerializer.new(@comment)
|
||||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
||||||
@ -28,7 +31,7 @@ module ActiveModel
|
|||||||
serializer = PostSerializer.new(@anonymous_post)
|
serializer = PostSerializer.new(@anonymous_post)
|
||||||
adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -13,16 +13,40 @@ module ActiveModel
|
|||||||
@second_post.comments = []
|
@second_post.comments = []
|
||||||
@first_post.author = @author
|
@first_post.author = @author
|
||||||
@second_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])
|
@serializer = ArraySerializer.new([@first_post, @second_post])
|
||||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_include_multiple_posts
|
def test_include_multiple_posts
|
||||||
assert_equal([
|
expected = [{
|
||||||
{title: "Hello!!", body: "Hello, world!!", id: 1, comments: [], author: {id: 1, name: "Steve K."}},
|
title: "Hello!!",
|
||||||
{title: "New Post", body: "Body", id: 2, comments: [], author: {id: 1, name: "Steve K."}}
|
body: "Hello, world!!",
|
||||||
], @adapter.serializable_hash)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -14,6 +14,8 @@ module ActiveModel
|
|||||||
@post.author = @author
|
@post.author = @author
|
||||||
@first_comment.post = @post
|
@first_comment.post = @post
|
||||||
@second_comment.post = @post
|
@second_comment.post = @post
|
||||||
|
@blog = Blog.new(id: 1, name: "My Blog!!")
|
||||||
|
@post.blog = @blog
|
||||||
|
|
||||||
@serializer = PostSerializer.new(@post)
|
@serializer = PostSerializer.new(@post)
|
||||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
||||||
|
|||||||
@ -9,11 +9,14 @@ module ActiveModel
|
|||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@author.bio = nil
|
@author.bio = nil
|
||||||
@author.roles = []
|
@author.roles = []
|
||||||
|
@blog = Blog.new(id: 23, name: 'AMS Blog')
|
||||||
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
||||||
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@post.comments = [@comment]
|
@post.comments = [@comment]
|
||||||
|
@post.blog = @blog
|
||||||
@anonymous_post.comments = []
|
@anonymous_post.comments = []
|
||||||
|
@anonymous_post.blog = nil
|
||||||
@comment.post = @post
|
@comment.post = @post
|
||||||
@comment.author = nil
|
@comment.author = nil
|
||||||
@post.author = @author
|
@post.author = @author
|
||||||
@ -39,6 +42,7 @@ module ActiveModel
|
|||||||
body: 'Body',
|
body: 'Body',
|
||||||
links: {
|
links: {
|
||||||
comments: ["1"],
|
comments: ["1"],
|
||||||
|
blog: "999",
|
||||||
author: "1"
|
author: "1"
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
@ -51,6 +55,7 @@ module ActiveModel
|
|||||||
title: 'New Post',
|
title: 'New Post',
|
||||||
links: {
|
links: {
|
||||||
comments: ["1"],
|
comments: ["1"],
|
||||||
|
blog: "999",
|
||||||
author: "1"
|
author: "1"
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
@ -61,7 +66,7 @@ module ActiveModel
|
|||||||
serializer = PostSerializer.new(@anonymous_post)
|
serializer = PostSerializer.new(@anonymous_post)
|
||||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
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
|
end
|
||||||
|
|
||||||
def test_include_type_for_association_when_different_than_name
|
def test_include_type_for_association_when_different_than_name
|
||||||
@ -101,6 +106,7 @@ module ActiveModel
|
|||||||
id: "42",
|
id: "42",
|
||||||
links: {
|
links: {
|
||||||
comments: ["1"],
|
comments: ["1"],
|
||||||
|
blog: "999",
|
||||||
author: "1"
|
author: "1"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@ -109,6 +115,7 @@ module ActiveModel
|
|||||||
id: "43",
|
id: "43",
|
||||||
links: {
|
links: {
|
||||||
comments: [],
|
comments: [],
|
||||||
|
blog: nil,
|
||||||
author: nil
|
author: nil
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
|||||||
@ -8,10 +8,13 @@ module ActiveModel
|
|||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@author.bio = nil
|
@author.bio = nil
|
||||||
|
@blog = Blog.new(id: 23, name: 'AMS Blog')
|
||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@first_post.comments = []
|
@first_post.comments = []
|
||||||
@second_post.comments = []
|
@second_post.comments = []
|
||||||
|
@first_post.blog = @blog
|
||||||
|
@second_post.blog = nil
|
||||||
@first_post.author = @author
|
@first_post.author = @author
|
||||||
@second_post.author = @author
|
@second_post.author = @author
|
||||||
@author.posts = [@first_post, @second_post]
|
@author.posts = [@first_post, @second_post]
|
||||||
@ -22,16 +25,16 @@ module ActiveModel
|
|||||||
|
|
||||||
def test_include_multiple_posts
|
def test_include_multiple_posts
|
||||||
assert_equal([
|
assert_equal([
|
||||||
{ title: "Hello!!", body: "Hello, world!!", id: "1", 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: [], author: "1" } }
|
{ title: "New Post", body: "Body", id: "2", links: { comments: [], blog: nil, author: "1" } }
|
||||||
], @adapter.serializable_hash[:posts])
|
], @adapter.serializable_hash[:posts])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_limiting_fields
|
def test_limiting_fields
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, fields: ['title'])
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, fields: ['title'])
|
||||||
assert_equal([
|
assert_equal([
|
||||||
{ title: "Hello!!", links: { comments: [], author: "1" } },
|
{ title: "Hello!!", links: { comments: [], blog: "999", author: "1" } },
|
||||||
{ title: "New Post", links: { comments: [], author: "1" } }
|
{ title: "New Post", links: { comments: [], blog: nil, author: "1" } }
|
||||||
], @adapter.serializable_hash[:posts])
|
], @adapter.serializable_hash[:posts])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,9 @@ module ActiveModel
|
|||||||
@second_post.author = @author
|
@second_post.author = @author
|
||||||
@first_post.comments = []
|
@first_post.comments = []
|
||||||
@second_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)
|
@serializer = AuthorSerializer.new(@author)
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
||||||
|
|||||||
@ -18,6 +18,8 @@ module ActiveModel
|
|||||||
@first_comment.author = nil
|
@first_comment.author = nil
|
||||||
@second_comment.post = @post
|
@second_comment.post = @post
|
||||||
@second_comment.author = nil
|
@second_comment.author = nil
|
||||||
|
@blog = Blog.new(id: 23, name: 'AMS Blog')
|
||||||
|
@post.blog = @blog
|
||||||
|
|
||||||
@serializer = PostPreviewSerializer.new(@post)
|
@serializer = PostPreviewSerializer.new(@post)
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
|
||||||
|
|||||||
@ -24,6 +24,8 @@ module ActiveModel
|
|||||||
@blog = Blog.new(id: 1, name: "My Blog!!")
|
@blog = Blog.new(id: 1, name: "My Blog!!")
|
||||||
@blog.writer = @author
|
@blog.writer = @author
|
||||||
@blog.articles = [@post]
|
@blog.articles = [@post]
|
||||||
|
@post.blog = @blog
|
||||||
|
@post_without_comments.blog = nil
|
||||||
|
|
||||||
@serializer = PostSerializer.new(@post)
|
@serializer = PostSerializer.new(@post)
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
||||||
@ -32,7 +34,7 @@ module ActiveModel
|
|||||||
def test_includes_comment_ids
|
def test_includes_comment_ids
|
||||||
assert_equal(["1", "2"], @adapter.serializable_hash[:posts][:links][:comments])
|
assert_equal(["1", "2"], @adapter.serializable_hash[:posts][:links][:comments])
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_includes_linked_comments
|
def test_includes_linked_comments
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments')
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments')
|
||||||
expected = [{
|
expected = [{
|
||||||
|
|||||||
@ -13,6 +13,10 @@ module ActiveModel
|
|||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@third_post = Post.new(id: 3, title: 'Yet Another 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 = []
|
@first_post.comments = []
|
||||||
@second_post.comments = []
|
@second_post.comments = []
|
||||||
@first_post.author = @author1
|
@first_post.author = @author1
|
||||||
@ -124,6 +128,7 @@ module ActiveModel
|
|||||||
id: "1",
|
id: "1",
|
||||||
links: {
|
links: {
|
||||||
comments: ["1", "2"],
|
comments: ["1", "2"],
|
||||||
|
blog: "999",
|
||||||
author: "1"
|
author: "1"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@ -132,6 +137,7 @@ module ActiveModel
|
|||||||
id: "3",
|
id: "3",
|
||||||
links: {
|
links: {
|
||||||
comments: [],
|
comments: [],
|
||||||
|
blog: nil,
|
||||||
author: "1"
|
author: "1"
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
|||||||
@ -13,6 +13,8 @@ module ActiveModel
|
|||||||
@first_comment.post = @post
|
@first_comment.post = @post
|
||||||
@second_comment.post = @post
|
@second_comment.post = @post
|
||||||
@post.author = @author
|
@post.author = @author
|
||||||
|
@blog = Blog.new(id: 1, name: "My Blog!!")
|
||||||
|
@post.blog = @blog
|
||||||
|
|
||||||
@serializer = PostSerializer.new(@post)
|
@serializer = PostSerializer.new(@post)
|
||||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
||||||
|
|||||||
5
test/fixtures/poro.rb
vendored
5
test/fixtures/poro.rb
vendored
@ -54,8 +54,13 @@ PostSerializer = Class.new(ActiveModel::Serializer) do
|
|||||||
attributes :title, :body, :id
|
attributes :title, :body, :id
|
||||||
|
|
||||||
has_many :comments
|
has_many :comments
|
||||||
|
belongs_to :blog
|
||||||
belongs_to :author
|
belongs_to :author
|
||||||
url :comments
|
url :comments
|
||||||
|
|
||||||
|
def blog
|
||||||
|
Blog.new(id: 999, name: "Custom blog")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
|
SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
|||||||
@ -28,14 +28,17 @@ module ActiveModel
|
|||||||
@author = Author.new(name: 'Steve K.')
|
@author = Author.new(name: 'Steve K.')
|
||||||
@author.bio = nil
|
@author.bio = nil
|
||||||
@author.roles = []
|
@author.roles = []
|
||||||
|
@blog = Blog.new({ name: 'AMS Blog' })
|
||||||
@post = Post.new({ title: 'New Post', body: 'Body' })
|
@post = Post.new({ title: 'New Post', body: 'Body' })
|
||||||
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
||||||
@post.comments = [@comment]
|
@post.comments = [@comment]
|
||||||
|
@post.blog = @blog
|
||||||
@comment.post = @post
|
@comment.post = @post
|
||||||
@comment.author = nil
|
@comment.author = nil
|
||||||
@post.author = @author
|
@post.author = @author
|
||||||
@author.posts = [@post]
|
@author.posts = [@post]
|
||||||
|
|
||||||
|
@post_serializer = PostSerializer.new(@post)
|
||||||
@author_serializer = AuthorSerializer.new(@author)
|
@author_serializer = AuthorSerializer.new(@author)
|
||||||
@comment_serializer = CommentSerializer.new(@comment)
|
@comment_serializer = CommentSerializer.new(@comment)
|
||||||
end
|
end
|
||||||
@ -63,7 +66,7 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
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)
|
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|
|
@comment_serializer.each_association do |name, serializer, options|
|
||||||
if name == :post
|
if name == :post
|
||||||
@ -77,6 +80,16 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user