Skip to content

Commit 27a5de2

Browse files
committed
Merge pull request #1633 from bf4/fix_reflection_block_context
Add serializer to association block context
2 parents d5833e8 + fa7b3af commit 27a5de2

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Breaking changes:
44

55
Features:
6+
- [#1633](https://github.com/rails-api/active_model_serializers/pull/1633) Yield 'serializer' to serializer association blocks. (@bf4)
67
- [#1616](https://github.com/rails-api/active_model_serializers/pull/1616) SerializableResource handles no serializer like controller. (@bf4)
78
- [#1618](https://github.com/rails-api/active_model_serializers/issues/1618) Get collection root key for
89
empty collection from explicit serializer option, when possible. (@bf4)

docs/general/serializers.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ has_one :blog, key: :site
4848
has_one :maker, virtual_value: { id: 1 }
4949
```
5050

51+
``ruby
52+
has_one :blog do |serializer|
53+
serializer.cached_blog
54+
end
55+
56+
def cached_blog
57+
cache_store.fetch("cached_blog:#{object.updated_at}") do
58+
Blog.find(object.blog_id)
59+
end
60+
end
61+
```
62+
5163
#### ::has_many
5264
5365
e.g.

lib/active_model/serializer/reflection.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,25 @@ def include_data(value = true)
5656
:nil
5757
end
5858

59+
# @param serializer [ActiveModel::Serializer]
60+
# @yield [ActiveModel::Serializer]
61+
# @return [:nil, associated resource or resource collection]
62+
# @example
63+
# has_one :blog do |serializer|
64+
# serializer.cached_blog
65+
# end
66+
#
67+
# def cached_blog
68+
# cache_store.fetch("cached_blog:#{object.updated_at}") do
69+
# Blog.find(object.blog_id)
70+
# end
71+
# end
5972
def value(serializer)
6073
@object = serializer.object
6174
@scope = serializer.scope
6275

6376
if block
64-
block_value = instance_eval(&block)
77+
block_value = instance_exec(serializer, &block)
6578
if block_value == :nil
6679
serializer.read_attribute_for_serialization(name)
6780
else

test/adapter/json_api/relationships_test.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ class RelationshipAuthorSerializer < ActiveModel::Serializer
3838
end
3939
end
4040

41-
has_many :roles do
41+
has_many :roles do |serializer|
4242
meta count: object.posts.count
43+
serializer.cached_roles
4344
end
4445

4546
has_one :blog do
@@ -60,14 +61,20 @@ class RelationshipAuthorSerializer < ActiveModel::Serializer
6061
end
6162
meta liked: object.likes.any?
6263
end
64+
65+
def cached_roles
66+
[
67+
Role.new(id: 'from-serializer-method')
68+
]
69+
end
6370
end
6471

6572
def setup
6673
@post = Post.new(id: 1337, comments: [], author: nil)
6774
@blog = Blog.new(id: 1337, name: 'extra')
6875
@bio = Bio.new(id: 1337)
6976
@like = Like.new(id: 1337)
70-
@role = Role.new(id: 1337)
77+
@role = Role.new(id: 'from-record')
7178
@profile = Profile.new(id: 1337)
7279
@location = Location.new(id: 1337)
7380
@reviewer = Author.new(id: 1337)
@@ -144,7 +151,7 @@ def test_relationship_block_link_meta
144151

145152
def test_relationship_meta
146153
expected = {
147-
data: [{ id: '1337', type: 'roles' }],
154+
data: [{ id: 'from-serializer-method', type: 'roles' }],
148155
meta: { count: 1 }
149156
}
150157
assert_relationship(:roles, expected)

0 commit comments

Comments
 (0)