Add optional meta field to relationships (#99) (#100)

* Add optional meta field to relationships (#99)

* Fix Rubocop's warnings.

* Minor syntax corrections.
This commit is contained in:
mperice 2020-07-07 16:22:25 +02:00 committed by GitHub
parent 6db86e0f4c
commit dd7f5ba415
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 2 deletions

View File

@ -317,6 +317,23 @@ class MovieSerializer
end
```
#### Meta on a Relationship
You can specify [relationship meta](http://jsonapi.org/format/#document-resource-object-relationships) by using the `meta:` option on the serializer. Relationship meta in JSON API is useful if you wish to provide non-standard meta-information about the relationship.
Meta can be defined either by passing a static hash or by using Proc to the `meta` key. In the latter case, the record and any params passed to the serializer are available inside the Proc as the first and second parameters, respectively.
```ruby
class MovieSerializer
include JSONAPI::Serializer
has_many :actors, meta: Proc.new do |movie_record, params|
{ count: movie_record.actors.length }
end
end
```
### Compound Document
Support for top-level and nested included associations through `options[:include]`.

View File

@ -283,6 +283,7 @@ module FastJsonapi
polymorphic: polymorphic,
conditional_proc: options[:if],
transform_method: @transform_method,
meta: options[:meta],
links: options[:links],
lazy_load_data: options[:lazy_load_data]
)

View File

@ -1,6 +1,6 @@
module FastJsonapi
class Relationship
attr_reader :owner, :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method, :links, :lazy_load_data
attr_reader :owner, :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method, :links, :meta, :lazy_load_data
def initialize(
owner:,
@ -17,6 +17,7 @@ module FastJsonapi
conditional_proc:,
transform_method:,
links:,
meta:,
lazy_load_data: false
)
@owner = owner
@ -33,6 +34,7 @@ module FastJsonapi
@conditional_proc = conditional_proc
@transform_method = transform_method
@links = links || {}
@meta = meta || {}
@lazy_load_data = lazy_load_data
@record_types_for = {}
@serializers_for_name = {}
@ -44,6 +46,8 @@ module FastJsonapi
output_hash[key] = {}
output_hash[key][:data] = ids_hash_from_record_and_relationship(record, serialization_params) || empty_case unless lazy_load_data && !included
add_meta_hash(record, serialization_params, output_hash) if meta.present?
add_links_hash(record, serialization_params, output_hash) if links.present?
end
end
@ -146,11 +150,19 @@ module FastJsonapi
record.public_send(links)
else
links.each_with_object({}) do |(key, method), hash|
Link.new(key: key, method: method).serialize(record, params, hash)\
Link.new(key: key, method: method).serialize(record, params, hash)
end
end
end
def add_meta_hash(record, params, output_hash)
output_hash[key][:meta] = if meta.is_a?(Proc)
FastJsonapi.call_proc(meta, record, params)
else
meta
end
end
def run_key_transform(input)
if transform_method.present?
input.to_s.send(*transform_method).to_sym

View File

@ -66,6 +66,7 @@ class MovieSerializer
has_many(
:actors,
meta: proc { |record, _| { count: record.actors.length } },
links: {
actors_self: :url,
related: ->(obj) { obj.url(obj) }

View File

@ -59,6 +59,13 @@ RSpec.describe FastJsonapi::ObjectSerializer do
)
end
describe 'has relationship meta' do
it do
expect(serialized['data']['relationships']['actors'])
.to have_meta('count' => movie.actors.length)
end
end
context 'with include' do
let(:params) do
{ include: [:actors] }