Home / Community
Home / Community

Using Jbuilder to customize JSON objects.

0db484da0a364dbadf287398f97a97dbby Nora Alvarado|

Aug 24, 2012


Usually when it comes to customizing JSON objects we use as_json, i.e., if we want to show a post and include its author and comments, we can set up a JSON response as follows:

def show
  @post = Post.find(params[:id])
  respond_to do |format|
    format.json { render json: @post.as_json(  only: [ :id, :name, :content ],
          include: [ :author, { comments: { 
                     only: [ :id, :name, :content ]} }] )}

Yep, this works, but depending on the customization that we want for the JSON object, this code could turn very ugly.

So what would I suggest? Well, using the Jbuilder gem is a good call. You can find it allready added in your Gemfile (if using Rails 3.2 or later, if not, just add it to your Gemfile), you only need to uncomment the line and run Bundle.

# To use Jbuilder templates for JSON
# gem 'jbuilder'

You can either use Jbuilder stand-alone or directly as an ActionView template language. When required in Rails, you can create views à-la show.json.jbuilder (the json is already yielded)

For example, you can use Jbuilder to override the to_json or as_json methods on your models or presenters.

def to_json
  Jbuilder.encode do |json|
    json.(self, :id, :name, :content)
    json.author(self.author, :name)
    json.comments(self.comments, :id, :name, :content)

And now your controller action would look (so much better) like this:

def show
  @post = Post.find(params[:id])

Also can use Jbuilder as templates, i.e


json.(@post, :id, :name, :published_at)
json.author(@post.author, :id, :name)
json.comments(@post.comments, :id, :name, :content)

We can even use partials on those templates:


json.comments @post.comments do |json, comment|
  json.partial! comment 

So there you have it, an easy and cleaner way to handle your custom JSONs objects. Do you have another way to do it? If so, we would like to know your tips and tricks.

blog comments powered byDisqus