The difference between Render and Redirect in Rails

Find out the difference between Render and Redirect in Rails

This article was updated on 16/11/2018. Thanks to folk in the comments for some great additions!

To a brand new Rails developer the controller methods render and redirect_to might seem very similar. They both appear at the bottom of your controller method and they both (when done correctly) end up showing a page in your web browser.

They both do very different things however, and it is good to know the difference.

Render

Calling render will create a full response that is sent back to the browser.

If you don’t include a call to render in your controller action then it is assumed you are trying to render the view of the same name as your controller action inside a folder of the same name as your controller. This means that the following code will look for app/views/foos/my_action.html.erb;

class FoosController < ApplicationController
    def my_action
    end
end

If you want to render a different view within the same controller you can call render :action_name and it will know where to look.

You can specify views that belong to another controller by using render "widgets/show"

You can even just render an arbitary file, a leading slash will let Rails know what do to. This is useful if you want to share views between Rails applications on the same server. render "/users/another/apps/different_app/app/views/products/show"

You can render things other than views as well, they are covered in more detail in this great guide, examples of things you can render are;

  • JSON
  • Text
  • Status Codes

Debugging Render

Sometimes you want to see what is going to be rendered without inspecting inside of the browser. There is a rails method called render_to_string which can really help you out. This takes all the same options as render but returns a string instead of sending a response back to the browser.

Redirect

Redirect is concerned about telling the browser it needs to make a new request to a different location.

This could be a location within your application by calling something like;

redirect_to widgets_url

Or it can be to a completely different website;

redirect_to "https://tosbourn.com"

By default Rails uses the 302 redirect, which is a temporary redirect. If you know any that traffic going to a certain place should always end up at a different place you should consider setting the status code to 301, which is a perminant redirect.

redirect_to widgets_url, status: 301

There is a great guide on the different status codes you should be worried about in this guide about HTTP status codes to be worried about for SEO

Know when to use each one

You should not make the browser need to make a fresh call unless you really have to, so always question when you are using redirect_to and if it is the right thing, or perhaps a render would be better.

A render doesn’t change the URL of the page you are visiting, which can lead to a confusing user experience if they visit /foo but because of some render magic start seeing a layout associated with /bar.

If you call render :new from a different controller only the view will be rendered not any of the other logic within the method i.e. instance variables (@var). However if you use redirect_to you can use instance variables within the view as redirect_to hits the controller (thanks Sami B & Shane!).

If you use render instead of redirect_to when setting error messages you should use flash.now[:error] and not flash[:error]. This is because the flash message may not show up on the page that is rendered but will show up on the next page that is visited leading to a confusing user experience (thanks Ed!).


Recent posts View all

Ruby

Forcing a Rails database column to be not null

How you can force a table column to always have something in it with Rails

Writing Marketing

We've deleted an article's worth of unhelpful words

We've improved several pages across our site by removing words that add no value, and often detract from the article.