In Rails, how do you render JSON using a view?

Learn in rails, how do you render json using a view? with practical examples, diagrams, and best practices. Covers ruby-on-rails, ruby, json development techniques with visual explanations.

Rendering JSON in Rails Using Views

Rendering JSON in Rails Using Views

Discover how to leverage Rails views (.json.jbuilder or .json.erb) for flexible and maintainable JSON responses, moving beyond simple render json: calls.

Rails applications often serve JSON data to front-end clients, APIs, or mobile applications. While render json: @object is convenient for simple cases, it quickly becomes unmanageable when you need to customize attribute selection, include associations, or apply complex transformations. This article explores how to use dedicated view templates (like .json.jbuilder or .json.erb) to define your JSON structure, offering a more robust, maintainable, and flexible approach to rendering JSON in Rails.

Why Use Views for JSON?

Using views for JSON rendering brings several benefits that align with Rails' convention over configuration philosophy and promote better code organization:

A flowchart diagram illustrating the decision process for choosing JSON rendering methods in Rails. Starts with 'Need JSON Response?'. Decision 1: 'Simple object/hash?'. If yes, 'render json: object'. If no, Decision 2: 'Complex structure, associations, conditional logic?'. If yes, 'Use Jbuilder/ERB Views'. If no, 'Consider custom serializer'. Arrows indicate flow. Clean, technical style.

Decision Flow for JSON Rendering in Rails

Rendering JSON with Jbuilder

Jbuilder is a gem included by default in new Rails applications, providing a simple DSL for building JSON structures. It allows you to define your JSON response using Ruby code within a .json.jbuilder template, making it highly readable and flexible.

First, ensure you have Jbuilder in your Gemfile (it should be there by default):

gem 'jbuilder'

Then, in your controller, you simply render the template:

class Api::V1::PostsController < ApplicationController
  def show
    @post = Post.find(params[:id])
    # Rails automatically looks for show.json.jbuilder
    # if the request format is JSON.
    # No explicit render call needed if convention is followed.
  end

  def index
    @posts = Post.all
  end
end

Example controller actions for show and index

Now, let's create the Jbuilder templates. For the show action, you might want to include the post's author and comments:

json.extract! @post, :id, :title, :content, :created_at
json.author do
  json.id @post.author.id
  json.name @post.author.name
end
json.comments @post.comments do |comment|
  json.extract! comment, :id, :body, :created_at
  json.commenter comment.commenter.name
end

Jbuilder template for a single post with author and comments

For the index action, you'd typically render a collection of posts:

json.array! @posts do |post|
  json.extract! post, :id, :title, :created_at
  json.author_name post.author.name
  json.comments_count post.comments.count
end

Jbuilder template for a collection of posts

Rendering JSON with ERB Templates

While Jbuilder is purpose-built for JSON, you can also use standard ERB templates (.json.erb) to generate JSON. This approach gives you full control using Ruby's built-in to_json methods or by manually constructing hashes and converting them. It's less common than Jbuilder but offers maximum flexibility if you prefer standard Ruby and don't want to learn Jbuilder's DSL.

<%# app/views/api/v1/products/show.json.erb %>
<% product_data  = {
  id: @product.id,
  name: @product.name,
  price: @product.price,
  description: @product.description,
  category: {
    id: @product.category.id,
    name: @product.category.name
  }
} %>
<%= product_data.to_json %>

ERB template for a single product

<%# app/views/api/v1/products/index.json.erb %>
<% products_array  = @products.map do |product|
  {
    id: product.id,
    name: product.name,
    price: product.price
  }
end %>
<%= products_array.to_json %>

ERB template for a collection of products