Skip to content

Commit 1b26e39

Browse files
committed
Add renderer option to render relationship only.
1 parent f6c0ce5 commit 1b26e39

File tree

2 files changed

+137
-7
lines changed

2 files changed

+137
-7
lines changed

lib/jsonapi/renderer/document.rb

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def initialize(params = {})
1212
@fields = _symbolize_fields(params[:fields] || {})
1313
@jsonapi = params[:jsonapi]
1414
@include = JSONAPI::IncludeDirective.new(params[:include] || {})
15+
@relationship = params[:relationship]
1516
end
1617

1718
def to_hash
@@ -23,14 +24,18 @@ def to_hash
2324

2425
def document_hash
2526
{}.tap do |hash|
26-
if @data != :no_data
27-
hash.merge!(data_hash)
28-
elsif @errors.any?
29-
hash.merge!(errors_hash)
27+
if @relationship
28+
hash.merge!(relationship_hash)
29+
else
30+
if @data != :no_data
31+
hash.merge!(data_hash)
32+
elsif @errors.any?
33+
hash.merge!(errors_hash)
34+
end
35+
hash[:links] = @links if @links.any?
36+
hash[:meta] = @meta unless @meta.nil?
3037
end
31-
hash[:links] = @links if @links.any?
32-
hash[:meta] = @meta unless @meta.nil?
33-
hash[:jsonapi] = @jsonapi unless @jsonapi.nil?
38+
hash[:jsonapi] = @jsonapi unless @jsonapi.nil?
3439
end
3540
end
3641

@@ -43,6 +48,31 @@ def data_hash
4348
end
4449
end
4550

51+
def relationship_hash
52+
rel_name = @relationship.to_sym
53+
data = @data.jsonapi_related([rel_name])[rel_name]
54+
included =
55+
if @include.key?(rel_name)
56+
ResourcesProcessor.new(data, @include[rel_name], @fields)
57+
.process
58+
.flatten!
59+
else
60+
[]
61+
end
62+
63+
res = @data.as_jsonapi(fields: [rel_name], include: [rel_name])
64+
rel = res[:relationships][rel_name]
65+
links = (rel[:links] || {}).merge(@links)
66+
meta = (rel[:meta] || {}).merge(@meta || {})
67+
68+
{}.tap do |hash|
69+
hash[:data] = rel[:data]
70+
hash[:included] = included if included.any?
71+
hash[:links] = links if links.any?
72+
hash[:meta] = meta unless meta.nil?
73+
end
74+
end
75+
4676
def errors_hash
4777
{}.tap do |hash|
4878
hash[:errors] = @errors.flat_map(&:as_jsonapi)

spec/renderer_spec.rb

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,4 +455,104 @@ def as_jsonapi
455455

456456
expect(actual).to eq(expected)
457457
end
458+
459+
context 'when rendering a relationship' do
460+
it 'renders the linkage data only' do
461+
actual = subject.render(data: @users[0], relationship: :posts)
462+
expected = {
463+
data: [{ type: 'posts', id: '2' }],
464+
links: {
465+
self: 'http://api.example.com/users/1/relationships/posts',
466+
related: {
467+
href: 'http://api.example.com/users/1/posts',
468+
meta: {
469+
do_not_use: true
470+
}
471+
}
472+
},
473+
meta: {
474+
deleted_posts: 5
475+
}
476+
}
477+
478+
expect(actual).to eq(expected)
479+
end
480+
481+
it 'renders supports include parameter' do
482+
actual = subject.render(data: @users[0], relationship: :posts,
483+
include: 'posts.author')
484+
actual_included = actual.delete(:included)
485+
486+
expected = {
487+
data: [{ type: 'posts', id: '2' }],
488+
links: {
489+
self: 'http://api.example.com/users/1/relationships/posts',
490+
related: {
491+
href: 'http://api.example.com/users/1/posts',
492+
meta: {
493+
do_not_use: true
494+
}
495+
}
496+
},
497+
meta: {
498+
deleted_posts: 5
499+
}
500+
}
501+
expected_included = [
502+
{
503+
type: 'users',
504+
id: '1',
505+
attributes: {
506+
name: 'User 1',
507+
address: '123 Example st.'
508+
},
509+
relationships: {
510+
posts: {
511+
links: {
512+
self: 'http://api.example.com/users/1/relationships/posts',
513+
related: {
514+
href: 'http://api.example.com/users/1/posts',
515+
meta: {
516+
do_not_use: true
517+
}
518+
}
519+
},
520+
meta: {
521+
deleted_posts: 5
522+
}
523+
}
524+
},
525+
links: {
526+
self: 'http://api.example.com/users/1'
527+
},
528+
meta: {
529+
user_meta: 'is_meta'
530+
}
531+
},
532+
{
533+
type: 'posts',
534+
id: '2',
535+
attributes: {
536+
title: 'Post 2',
537+
date: 'today'
538+
},
539+
relationships: {
540+
author: {
541+
data: { type: 'users', id: '1' },
542+
links: {
543+
self: 'http://api.example.com/posts/2/relationships/author',
544+
related: 'http://api.example.com/posts/2/author'
545+
},
546+
meta: {
547+
author_active: true
548+
}
549+
}
550+
}
551+
}
552+
]
553+
554+
expect(actual).to eq(expected)
555+
expect(actual_included).to match_array(expected_included)
556+
end
557+
end
458558
end

0 commit comments

Comments
 (0)