Skip to content
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