Sinatra: Render or Redirect
At first glance, render and redirect appeared to be identical twins that I couldn’t tell apart. Many novice programmers initially find it difficult to distinguish between the responsibilities of the two due to the similarities in their code. So quite often newcomers can only guess when one should be used over the other. Now that I understand the different personalities of these twins, their differences seem so obvious. I mean, it’s in their names, for crying out loud!
Render, alludes to something you will see. And redirect, alludes to being directed somewhere. This can still be confusing because they both send you somewhere outside of the block they reside in. So I was still perplexed until I realized, though they both send you somewhere, erb (render) sends you to an erb file (in a Views folder) to reveal its contents to a user. While redirect sends you to code methods in a controller class (in a Controller folder) to get more instructions. One leads you to a file, the other leads you to a method. One is a file search, and the other an HTTP request route.
They work hand in hand so closely that their roles are often confused. And that’s not the only thing that’s confusing about them. For example, tell me, in the code below, which is render and which is redirect:
‘/’
‘/index’
‘/signup’
‘/signup’
‘/login’
‘/login’
You’re probably thinking, I’m not being fair because I didn’t preface the code with it’s matching redirect or erb. But that would’ve made it easy for you to quickly group them without having to even consider the code above. And that’s the problem! As a newcomer, what we see is the code above, which looks very similar so the two are easily confused. Consequently, when we get an error, we’re often hunting for it or a solution in the wrong place.
Now try sorting the same code with the corresponding erb and redirect in tact:
redirect ‘/’
erb : ‘/index’
erb : ‘/signup’
redirect ‘/signup’
redirect ‘/login’
erb :‘/login’
It’s definitely a quicker sort but the significance of the difference is still elusive. You can say one’s for show and one’s for go but if you don’t know how they work together behind the scenes, all you hear is Charlie Brown adult-speak, ‘wah wah wah and wah wah wah.’
So here’s how they work together step by step.
Step 1: You want a user to do something like read a website’s homepage, well they have to see the homepage to read it. Use the GET method when you want to show the user something to see. Use erb to render a file for the user to see and those files are stored in the views folder. We can configure our controller to set views so we don’t have to include views in our methods. A website’s homepage route is often represented with ‘/’ and the file is named index.
NOTE: The method route is get ‘/’ The render call is erb : ‘/index’
get ‘/’ do
erb : ‘/index’
end
get is the method and ‘/’ is the name that will be called to carry out this task. The erb code passed into the do/end block requires the homepage file named index (which is in the views folder) be shown to the user so they can read it.
Step 2: Reading the homepage is a simple process because the user is only reading it. But suppose the user decides to log in. They click login to see the login form. Remember, use the GET method when you want to show the user something to see. Notice that in step 1 the method route and render call have different names ( ‘/‘ & : ‘/index’), but in step 2 the names are very similar ( ‘/login’ & : ‘/login’). This is very confusing when first encountered because the code doesn’t appear to follow the same pattern but at the same time there are similarities in the code syntax though their function is different.
NOTE:
The method route is get ‘/login’
The render call is erb : ‘/login’
get ‘/login’ do
erb : ‘/login’
end
get ‘/login’ is the method and name that will be called. And the code passed into the do/end block will run. That code is requiring that the file named login (which is in the views folder) be shown to the user so they can fill in their information to log in.
Step 3: Now the user isn’t simply reading the login, they must input information and submit it to get logged in. This input information is handled by a POST method and then the user should be shown the user page specific to them. Due to separation of concerns, each method has only one job. This is where redirect comes in. Since it’s the GET method’s job to show things to the user, the POST method has to redirect to the GET method after it authenticates the user information.
NOTE:
The method route is post ‘/login’
The redirect call is redirect “/users/#{@user.id}”
post ‘/login’ do
(code to authenticate & assign @user based on the user’s input and if it’s authenticated…)
redirect “/users/#{@user.id}”
end
post is the method and ‘/login’ is the name that will be called. If the user input is authenticated, then it’s redirected to a GET method to show the user their own page. So no views folder here, we’re headed to the controllers folder where the matching method route lives. Double quotation marks are used in the redirect call to interpolate or distinguish each unique user from any other user.
Step 4: And now we can show the user’s page with the GET method in step 4 that matches the redirect call in step 3.
NOTE:
The method route is get ‘/users/:id’
The render call is erb : ‘/users/show’
get ‘/users/:id’ do
@user = User.find_by(id: params[:id])
erb : ‘/users/show’
end
get is the method and ‘users/:id’ is the route name matched to “/users/#{@user.id}” in step 3. Now step 3 passes in the interpolated value to find the correct user and assign to the instance variable @user. This assignment is used so it’s accessible in the erb file. The user’s show page is a file named show and it’s located in the views folder in a folder called users. And now a show page specific to the authenticated user can be shown.
Hopefully you can now tell the twins apart based on their personality, or rather their responsibilities. Render (erb) points to a file page of data (shown to the user) that resides in the views folder. Redirect points to a method that resides in the controllers folder. Now that you know how they work together behind the scenes, you understand what it means that render (erb) is for show and redirect is for go.