In my rails 3.2 app, I'm using jbuilder to render responses from my JSON api.
I want to provide a common structure to all API responses, and a layout would be the likely solution to keep my views DRY.
ex: I'd like every response to be of the following form :
{
status: "ok|error|redirect",
data: { ... JSON specific to the current view ... },
errors: [ ... ],
notes: [ ... ]
}
(where the value for data is a json structure provided by the view, everything else is from the layout)
However: I can't get the jbuilder layout yielding to the view correctly.
# in layout
json.data yield
# in view
json.some "value"
results in:
{"data":"{\"some\":\"value\"}"} # arg! my json has become a string
Trying things another way:
# in layout
yield
# in view
json.data do |json|
json.some "value"
end
results in :
{}
Has anyone had success doing this with jbuilder, or another json templating gem/method?
This juilder github issue suggests it's possible, but indicates others are having similar issues.
I see rabl (https://github.com/nesquena/rabl/) is supposed to support layouts (https://github.com/nesquena/rabl/wiki/Using-Layouts), but I've decided not to use it for other reasons (rabl makes complex json structures a nightmare, particularly when trying to control object roots etc).
I'll give you an alternative based on a solution we came up with:
# app/helpers/application_helper.rb
module ApplicationHelper
def envelope(json, status, errors, notes)
json.status status
json.data do
yield if block_given?
end
json.errors errors
json.notes notes
end
end
then, in the view, you can call envelope and include your json code like:
# app/views/api/v1/test/show.json.jbuilder
envelope(json, "OK" ) do
json.some 'value'
end