Wrapping Our Heads Around Render and Redirect
This past week at Flatiron School, we learned about Rack and Sinatra and started a brief overview of Ruby on Rails. To say that the beginning of the week was filled with an overwhelming amount of information would be an understatement. For many of us, concepts like HTTP verbs, RESTful routes, and the MVC framework were completely new. Lessons on these concepts came with some entirely new vocabulary, syntax, and file structure.
There were two new words in our lessons that seemed very similar, which caused me to question the actual difference between the two terms. I decided to do some research regarding the terms “render” and “redirect_to”, which seemed to be used interchangeably within different controller actions. It turns out, these terms are not interchangeable and there are definite cases where one term is more appropriate than the other.
Proper Naming
To begin, it is important to know that the naming of our controllers and actions is very important in Rails. This is because Rails will assume that things are named a certain way in our program and will execute them based on those names. First, our controller and its actions have to be named the same way we named them in our “routes.rb” file when we mapped a specific type of HTTP request to them. Second, once Rails hits the end of a controller action, it will send over any instance variables within the action to the view file with the same name as the action in the folder with the same name as the controller. Obviously, we can name and store our files however we like, but we will have to specifically tell Rails which file we want to render.
Render vs. Redirect
Rails will implicitly render the view file with the same name as the controller action, but there are times when we will want to redirect the user to a completely different page. This will typically happen after information has been submitted to create or edit something (in this blog entry, we will be dealing with the action of creating a new post on a web application). After creating a new post, we would want to display the Show page for this specific post. Therefore, it would not be necessary, and would not make sense, to have a “create.html.erb” view file that is rendered after creating a new post. In this case, we would instead “redirect” to the Show page for that post.
The distinction here is that our application will treat the “redirect” as a completely new HTTP request, which will look for the Show page of the created post and render it normally. It also means that any instance variables set in the #create controller action will be wiped out.
Wiped Out?!?!
You may notice a problem with that last statement if we only choose to “redirect” at the end of the controller action for creating a post. What happens if the creation of the post is unsuccessful? Maybe the user entered a post message that is too long (if our application only accepts post messages that are 140 characters long –– a totally random, but completely plausible, example. In that case, we would want to “render” the view for a different controller action, specifically the same action that created the form the user just submitted (the #new action).
In this scenario, the view page will be passed the instance variables from the current controller action. So, let’s say our user tried to #create a post, which will be stored in the “@post” instance variable, but the post fails to save due to the length of the post’s message. By rendering the #new action in the scenario, the New view will be passed the “@post” instance variable from the #create action we were just dealing with. Instead of annoying the user by displaying a blank new form, we can just identify the errors and have the user try again.
This Scenario in (Incomplete) Code
The error condition in the code above is going to render the same form that we rendered in the #new action, but this time, “@post” will be the object that we just tried to create but failed to save.
This Scenario in (Complete) Code
Once we add in the code to set up a new post based on the form info and display our success or error messages, our code to represent the key difference between “render” and “redirect” would look like this:
Key Difference
In summary, the key difference between “render” and “redirect” is that Rails will treat the “redirect” as a completely new HTTP request and wipe out any of the instance variables stored in the current controller action. This can have a major impact on our users’ experience, so it is crucial to understand the difference and make the right choices in our code!