Ruby on Rails – Rendering



In Rails, the controller is responsible for processing the incoming request and creating the response to be sent back to the client.

The controller uses mainly the following three ways to create the response

  • render
  • render_to
  • head

The render Method

By default, controllers in Rails automatically render views with names that correspond to valid routes. The render method is often called implicitly.

If you have a BooksController class with index action as defined below:

class BooksController < ApplicationController
  def index
    @books = Book.all
  end
end

You also have the routes defined as:

resources :books

And a view file index.html.erb is also in place.

There is no explicit call to render at the end of the index action, as Rails follows the principle "convention over configuration", according to which you do not explicitly render something at the end of a controller action, Rails automatically looks for the action_name.html.erb template in the controller's view path and render it.

Here, Rails automatically looks for a view template in app/views/books/index.html.erb and renders it.

However, if you want to override the default behaviour and render a different template, partial, or even JSON, you can explicitly call render.

class BooksController < ApplicationController
  def index
    @book = Book.all
    render 'list'
  end
end

This will render app/views/books/list.html.erb instead of index.html.erb.

Incidentally, there’s also a render_to_string method. It takes exactly the same options as render, but it returns a string instead of sending a response back to the browser.

You can also send an HTML string back to the browser by using the :html option to render method. This is especially useful when you're rendering a small snippet of HTML code instead of the entire template.

render html: "<h1>Welcome to the Books Section</h1>".html_safe

The .html_safe clause is required to prevent Rails from escaping HTML.

Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser:

render json: @book

Likewise, Rails also has built-in support for converting objects to XML and rendering that XML back to the caller:

render xml: @book

In both the cases, you don't need to call to_json or to_xml on the object that you want to render. If you use the :xml option, render will automatically call to_xml for you. Similarly, if you use the :json option, render will automatically call to_json for you.

Rendering JavaScript is also possible with the render js method.

render js: "alert('Hello World');"

The :plain option lets you can send plain text - with no markup at all - back to the browser.

render plain: "OK"

Note: The text is rendered without using the current layout. To put the text into the current layout, you need to add the layout: true option and use the .text.erb extension for the layout file.

The redirect_to Method

The redirect_to method does something completely different: it tells the browser to send a new request for a different URL. This method needs to be explicitly called.

The key difference between render vs. redirect_to methods is that – "while the render method returns a response directly (HTML, JSON, etc.), the redirect_to method sends an HTTP redirect to another URL."

class BooksController < ApplicationController
  def show
    @book = Book.find(params[:id])
    redirect_to books_path
  end
end

This changes the URL to /books and performs a new request.

You can use redirect_back to return the user to the page they just came from. Note that these methods do not halt and return immediately from method execution, but simply set HTTP responses.

Rails uses returns the status code 302, which indicates a temporary redirect, when you call redirect_to. To use a different status code, such as 301, (it stands for a permanent redirect) you can use the :status option:

redirect_to books_path, status: 301

The head Method

The head method can be used to send responses with only headers to the browser. The head method optionally accepts a number representing an HTTP status code. For example, you can return only an error header:

head :bad_request

Or you can use other HTTP headers to convey other information:

head :created, location: book_path(@book)

The options argument is interpreted as a hash of header names and values.

Advertisements