Serve up JSON Metadata in Rails
March 28th 2010So Imagine that you’re using will_paginate in your Rails app.
In order for the display to update properly, you’ve gotta give the view back the current page number, the number of records on a page, and the total number of records you allow. You might do that like this through json:
@articles = Article.paginate(:page => params[:page])
render :json => { :data => @articles,
:total => Article.count,
:page => params[:page] || 0,
:per_page => Article.per_page
}
end
But then that muddles up your pretty JSON interface with a bunch of metadata. Say goodbye to using JesterJS, or any other ActiveResource out there. It also means you miss out on the respond_with magic of Rails 3.
But hey – HTTP already serves up this metadata in the form of headers. Why don’t we just set all of these values in the appropriate header?
if params[:format] == :json
response.headers['X-JSON'] = opts.to_json
elsif params[:format] == :xml
response.headers['X-XML'] = opts.to_xml(:root => 'metadata')
end
end
@articles = Article.paginate(:page => params[:page])
metadata :total => Article.count,
:page => params[:page] || 0,
:per_page => Article.per_page
respond_with @articles
end
Pretty and DRY, all at the same time! Looks like a win!
Since prototype automatically evals the X-JSON header, we can write a tiny bit of javascript to update our view accordingly:
if typeof metadata !== "undefined" && metadata !== null
$$current_pageeachfunctionelt
eltupdatemetadatapage;
;
$$total_recordseachfunctionelt
eltupdatemetadatacount
;
;