-
Notifications
You must be signed in to change notification settings - Fork 335
Using Layouts
It may be desirable to use a common layout file for all JSON responses to include a response code or other metadata. For example, the Google Geocoder API returns a status
field, and all response data under results
.
When returning JSON data, the rails application will merge controller output with a layout file via yield
, just as can be done with view layout files. Below is an example json layout file.
Note: We use the Yajl (
yajl-ruby
) binding in the examples below, but choose any JSON parser you like.
Filename:
app/views/layouts/application.json.erb
You can do this two (or even more) different ways:
{
"metadata": <%= @metadata.to_json.html_safe %>,
"error": <%= @error.to_json.html_safe %>,
"result": <%= yield %>
}
<%=
raw({
metadata: @metadata,
error: @error,
result: Yajl::Parser.parse(yield)
}.to_json)
%>
Filename:
app/views/layouts/application.json.haml
Add haml
to the Gemfile:
gem 'haml'
:plain
{
"status": #{response.status},
"error": #{@error.to_json.html_safe},
"result": #{yield}
}
Filename:
app/views/layouts/application.json.json_builder
Add json_builder
to the Gemfile:
gem 'json_builder'
status response.status
error @error.to_json.html_safe
result JSON.parse(yield)
Filename:
app/views/layouts/application.json.rabl
node(:status) { response.status }
node(:error) { @error.to_json.html_safe }
node(:result) do
Yajl::Parser.parse(yield)
end
In this case, the rendered output of your .rabl
will appear under the result
field (or wherever the yield is placed in the layout file). The controller can pass metadata and error values via instance variables.
This example may not work with Ruby 1.9 (1.9.2 and 1.9.3 in my case). So, if it raises No block given (yield)
, try to use Erb layouts (the second one is better one), I haven't realize yet how to solve this problem.
Note that
html_safe
prevents Rails from auto-escaping the JSON output. Theraw
helper can also be used. This blog post explains the difference.