Skip to content

Commit 0d84b02

Browse files
authored
Add hook for default jsonapi object. (#37)
* Add hook for default jsonapi object. * Refactor renderers.
1 parent 3b1357e commit 0d84b02

File tree

4 files changed

+73
-42
lines changed

4 files changed

+73
-42
lines changed

lib/jsonapi/rails/action_controller.rb

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ def deserializable_resource(key, options = {}, &block)
4242
end
4343
end
4444

45+
def jsonapi_object
46+
nil
47+
end
48+
4549
def jsonapi_expose
4650
{
4751
url_helpers: ::Rails.application.routes.url_helpers

lib/jsonapi/rails/railtie.rb

+5-16
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,13 @@ class Railtie < ::Rails::Railtie
2727
::ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = PARSER
2828
end
2929

30-
::ActionController::Renderers.add(:jsonapi) do |resources, options|
31-
self.content_type ||= Mime[:jsonapi]
30+
RENDERERS.each do |name, renderer|
31+
::ActionController::Renderers.add(name) do |resources, options|
32+
# Renderer proc is evaluated in the controller context.
33+
self.content_type ||= Mime[:jsonapi]
3234

33-
# Renderer proc is evaluated in the controller context.
34-
if (pagination_links = jsonapi_pagination(resources))
35-
(options[:links] ||= {}).merge!(pagination_links)
35+
renderer.render(resources, options, self).to_json
3636
end
37-
options[:expose] = jsonapi_expose.merge!(options[:expose] || {})
38-
39-
RENDERERS[:jsonapi].render(resources, options).to_json
40-
end
41-
42-
::ActionController::Renderers.add(:jsonapi_error) do |errors, options|
43-
# Renderer proc is evaluated in the controller context.
44-
options = options.merge(_jsonapi_pointers: jsonapi_pointers)
45-
self.content_type ||= Mime[:jsonapi]
46-
47-
RENDERERS[:jsonapi_error].render(errors, options).to_json
4837
end
4938
end
5039
end

lib/jsonapi/rails/renderer.rb

+14-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@ def initialize(renderer = JSONAPI::Serializable::SuccessRenderer.new)
99
freeze
1010
end
1111

12-
def render(resources, options)
13-
opts = options.dup
14-
opts[:jsonapi] = opts.delete(:jsonapi_object)
12+
def render(resources, options, controller)
13+
options = options.dup
1514

16-
@renderer.render(resources, opts)
15+
if (pagination_links = controller.jsonapi_pagination(resources))
16+
(options[:links] ||= {}).merge!(pagination_links)
17+
end
18+
options[:expose] =
19+
controller.jsonapi_expose.merge!(options[:expose] || {})
20+
options[:jsonapi] =
21+
options[:jsonapi_object] || controller.jsonapi_object
22+
23+
@renderer.render(resources, options)
1724
end
1825
end
1926

@@ -24,8 +31,10 @@ def initialize(renderer = JSONAPI::Serializable::ErrorsRenderer.new)
2431
freeze
2532
end
2633

27-
def render(errors, options)
34+
def render(errors, options, controller)
35+
options = options.merge(_jsonapi_pointers: controller.jsonapi_pointers)
2836
# TODO(beauby): SerializableError inference on AR validation errors.
37+
2938
@renderer.render(errors, options)
3039
end
3140
end

spec/action_controller_spec.rb

+50-21
Original file line numberDiff line numberDiff line change
@@ -95,35 +95,64 @@ def create
9595
end
9696
end
9797

98-
describe '#render jsonapi:' do
99-
controller do
100-
def index
101-
serializer = Class.new(JSONAPI::Serializable::Resource) do
102-
type :users
103-
attribute :name
98+
describe '#render' do
99+
context 'when calling render jsonapi: user' do
100+
controller do
101+
def index
102+
serializer = Class.new(JSONAPI::Serializable::Resource) do
103+
type :users
104+
attribute :name
105+
end
106+
user = OpenStruct.new(id: 1, name: 'Lucas')
107+
108+
render jsonapi: user, class: serializer
104109
end
105-
user = OpenStruct.new(id: 1, name: 'Lucas')
110+
end
111+
112+
subject { JSON.parse(response.body) }
113+
let(:serialized_user) do
114+
{
115+
'data' => {
116+
'id' => '1',
117+
'type' => 'users',
118+
'attributes' => { 'name' => 'Lucas' }
119+
}
120+
}
121+
end
122+
123+
it 'renders a JSON API success document' do
124+
get :index
106125

107-
render jsonapi: user, class: serializer
126+
expect(response.content_type).to eq('application/vnd.api+json')
127+
is_expected.to eq(serialized_user)
108128
end
109129
end
110130

111-
subject { JSON.parse(response.body) }
112-
let(:serialized_user) do
113-
{
114-
'data' => {
115-
'id' => '1',
116-
'type' => 'users',
117-
'attributes' => { 'name' => 'Lucas' }
131+
context 'when specifying a default jsonapi object' do
132+
controller do
133+
def index
134+
render jsonapi: nil
135+
end
136+
137+
def jsonapi_object
138+
{ version: '1.0' }
139+
end
140+
end
141+
142+
subject { JSON.parse(response.body) }
143+
let(:document) do
144+
{
145+
'data' => nil,
146+
'jsonapi' => { 'version' => '1.0' }
118147
}
119-
}
120-
end
148+
end
121149

122-
it 'renders a JSON API document' do
123-
get :index
150+
it 'renders a JSON API success document' do
151+
get :index
124152

125-
expect(response.content_type).to eq('application/vnd.api+json')
126-
is_expected.to eq(serialized_user)
153+
expect(response.content_type).to eq('application/vnd.api+json')
154+
is_expected.to eq(document)
155+
end
127156
end
128157
end
129158
end

0 commit comments

Comments
 (0)