Skip to content

Add serializer to association block context #1633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Breaking changes:

Features:
- [#1633](https://github.com/rails-api/active_model_serializers/pull/1633) Yield 'serializer' to serializer association blocks. (@bf4)
- [#1616](https://github.com/rails-api/active_model_serializers/pull/1616) SerializableResource handles no serializer like controller. (@bf4)
- [#1618](https://github.com/rails-api/active_model_serializers/issues/1618) Get collection root key for
empty collection from explicit serializer option, when possible. (@bf4)
Expand Down
12 changes: 12 additions & 0 deletions docs/general/serializers.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ has_one :blog, key: :site
has_one :maker, virtual_value: { id: 1 }
```

``ruby
has_one :blog do |serializer|
serializer.cached_blog
end

def cached_blog
cache_store.fetch("cached_blog:#{object.updated_at}") do
Blog.find(object.blog_id)
end
end
```

#### ::has_many

e.g.
Expand Down
15 changes: 14 additions & 1 deletion lib/active_model/serializer/reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,25 @@ def include_data(value = true)
:nil
end

# @param serializer [ActiveModel::Serializer]
# @yield [ActiveModel::Serializer]
# @return [:nil, associated resource or resource collection]
# @example
# has_one :blog do |serializer|
# serializer.cached_blog
# end
#
# def cached_blog
# cache_store.fetch("cached_blog:#{object.updated_at}") do
# Blog.find(object.blog_id)
# end
# end
def value(serializer)
@object = serializer.object
@scope = serializer.scope

if block
block_value = instance_eval(&block)
block_value = instance_exec(serializer, &block)
if block_value == :nil
serializer.read_attribute_for_serialization(name)
else
Expand Down
13 changes: 10 additions & 3 deletions test/adapter/json_api/relationships_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ class RelationshipAuthorSerializer < ActiveModel::Serializer
end
end

has_many :roles do
has_many :roles do |serializer|
meta count: object.posts.count
serializer.cached_roles
end

has_one :blog do
Expand All @@ -60,14 +61,20 @@ class RelationshipAuthorSerializer < ActiveModel::Serializer
end
meta liked: object.likes.any?
end

def cached_roles
[
Role.new(id: 'from-serializer-method')
]
end
end

def setup
@post = Post.new(id: 1337, comments: [], author: nil)
@blog = Blog.new(id: 1337, name: 'extra')
@bio = Bio.new(id: 1337)
@like = Like.new(id: 1337)
@role = Role.new(id: 1337)
@role = Role.new(id: 'from-record')
@profile = Profile.new(id: 1337)
@location = Location.new(id: 1337)
@reviewer = Author.new(id: 1337)
Expand Down Expand Up @@ -144,7 +151,7 @@ def test_relationship_block_link_meta

def test_relationship_meta
expected = {
data: [{ id: '1337', type: 'roles' }],
data: [{ id: 'from-serializer-method', type: 'roles' }],
meta: { count: 1 }
}
assert_relationship(:roles, expected)
Expand Down