what is the difference between link_to, redirect_to, and render?
From the Documentation:
Regarding rendering a view vs redirecting a request
. . . render tells Rails which view (or other asset) to use in constructing a response. The redirect_to method does something completely different: it tells the browser to send a new request for a different URL.
Regarding rendering a view
. . . render :action doesn't run any code in the target action . . .
Regarding redirecting a request
. . . Your code stops running and waits for a new request for the browser. It just happens that you've told the browser what request it should make next, by sending back an HTTP 302 status code.
Basically:
link_to is a helper method to generate URLs usually used in your views (.html.erb files)
render tells your controller to render a view without passing any data (say, from a form) to the next controller action.
redirect_to does a 302 page redirect, passing data (say, from a form) to either a controller action on your web app, or an external app (ex: google, facebook, a web article you liked, etc)
link_to
is for use in ERB templates. It outputs a link to a specific path or url.
redirect_to
is for use in controllers. It causes the client to request the specified path or url once the controller method exits.
render
is also for use in controllers. It causes Rails to render the specified template.
redirect_to
and render
may only be called once in a given controller method.
I actually just wrote a blog post about this. The most important bits are copied below (with modifications).
Controller Methods: render
vs. redirect_to
render
and redirect_to
are the two ways that controller actions end (generally speaking). To understand how they work, let's review what controllers do in a Rails app:
- A user tries to access a page.
(http://localhost:3000/books/index.html) - Under the hood, the browser sends an HTTP request for the specified path on the server.
(GET /books/index.html
) - The Rails routing system then looks up which controller corresponds to the given request path.
(books GET /books/index(.:format) books#index
) - The controller prepares some data and then tells the server what response (i.e., what HTTP header/body content) to send back to the client.
This last step occurs explicitly when you call render
or redirect_to
, or implicitly if you leave it out.
That is,
def index
@books = Book.all
end
is the same as
def index
@books = Book.all
render :index
end
render :index
says, ‘combine the data I've prepared (@books = Book.all
) with the books/index.html.erb
view template to generate a complete HTML document, then send that back to the client.’
redirect_to @book
says, ‘tell the client to start the whole process over again, issuing a new GET
request to url_for(@book)
.
If you omit both, the action will render a template with the same name as the action itself. In other words, you only need to call render
explicitly when the view template you want doesn’t match the action you’re rendering it from.
Note that not every controller action has a corresponding view template. Generally, #create
, #update
, and #destroy
(which are all routed to non-GET
HTTP requests) attempt to make some change to the database and then either redirect_to
some resource (if it succeeded) or re-render
the form that preceded it, along with any errors (if it failed).
As the official guides explain (emphasis mine),
These two methods [
render
andredirect_to
] represent the two basic action archetypes used in Action Controllers: Get-and-show and do-and-redirect. Most actions are variations on these themes.
View Methods: render
vs. link_to
render
is also used within view templates themselves. Rather than generating a complete HTML document, it's used to insert a partial view template into a larger one. Here's the upshot:
- You can create partial view template files to be inserted into your standard templates (think of them as modular page components).
- Filenames of partials must begin with an underscore (e.g.,
_nav.html.erb
). - Use
render 'nav'
if you want to include the_nav.html.erb
partial from a view located in the same folder. - Use
render 'shared/nav'
if you want to include the partial atapp/views/shared/_nav.html.erb
from any view in your project. - Various options and shorthand syntaxes exist for passing data into a partial, rendering multiple partials from a collection object, and more. See the guides for details.
link_to
is just a convenience method for inserting anchor tags (a href
tags) into your view templates. This is useful because a lot of the URLs you'll want to link to are other pages within your application, and those URLs can be referenced using objects or "helper methods", like so:
= link_to 'Back', books_path # renders as <a href="/books">Back</a>
= link_to 'View', @book # renders as <a href="/book/1">View</a> or similar
link_to is used in your view, and generates html code for a link
<%= link_to "Google", "http://google.com" %>
This will generate in your view the following html
<a href="http://google.com">Google</a>
redirect_to and render are used in your controller to reply to a request. redirect_to will simply redirect the request to a new URL, if in your controller you add
redirect_to "http://google.com"
anyone accessing your page will effectively be redirected to Google
render can be used in many ways, but it's mainly used to render your html views.
render "article/show"
This will render the view "app/views/article/show.html.erb"
The following link will explain the redirect_to and the render methods more in detail http://guides.rubyonrails.org/layouts_and_rendering.html