Routes in Rails

Jennifer Oh
The Startup
Published in
5 min readMay 30, 2019

A basic tutorial on how to use routes and controllers

Routes play a significant role in the creation of a website. It is how the user will be able to view and interact with the webpages of your site, which is why how you set up your routes page in your text editor is one of the most important features — if you can’t set up your routes, you won’t be able to properly have a functioning website. Luckily Ruby on Rails has helper methods built in to create routes. Although it’s convenient to use helper methods, it’s also important to be able to create customizable routes.

The paths that you have in your controllers is dependent on what your routes should be. As an example, I will be using two models (Owner and Pet) and two controllers (owners_controller and pets_controller) to display my routes. Ruby gives us generic and built-in routes when its given the following:

resources :owners
resources :pets
#You can also combine the two as such: resources :owners, :pets

This display is the same as such:

get 'owners/', to: 'owners/#index', as: 'owners'
get 'owners/new', to: 'owners#new', as: 'new_owner'
post 'owners/', to: 'owners#create'
get 'owners/:id', to: 'owners#show', as: 'owner'
get 'owners/:id/edit', to: 'owners#edit', as: 'edit_owner'
patch 'owners/:id', to: 'owners#update'
delete 'owners/:id', to: 'owners#destroy'
get 'pets/', to: 'pets/#index', as: 'pets'
get 'pets/new', to: 'pets#new', as: 'new_pet'
post 'pets/', to: 'pets#create'
get 'pets/:id', to: 'pets#show', as: 'pet'
get 'pets/:id/edit', to: 'pets#edit', as: 'edit_pet'
patch 'pets/:id', to: 'pets#update'
delete 'pets/:id', to: 'pets#destroy'

You can also customize the resources to display only certain CRUD actions:

resources :owners, only: [:index, :new, :create, :show]#This will only give you routes to the listed actionsget 'owners/', to: 'owners#index', as: 'owners'
get 'owners/new', to: 'owners#new', as: 'new_owner'
post 'owners/', to: 'owners#create'
get 'owners/:id', to: 'owners#show', as: 'owner'

get, post, patch, and delete are the HTTP verbs.

It instructs the server to transmit the data identified by the URL to the client. Data should never be modified on the server side as a result of a GET request. In this sense, a GET request is read-only.

‘owners/’ is the URL path that will be displayed in the address bar.

In the ‘owners#index’, the owners points to the controller and index is the action.

Finally, although as: ‘owners’ is not necessary, it is convenient to have, as you can use it instead of writing out the whole path when you write redirect_to in your controllers. After creating resources, you can type rails routes in your console to check your routes.

Let’s build out the controllers! I’ll only fill out the owners_controller as it will look similar to the pets_controller.

class OwnersController < ApplicationControllerdef index
@owners = Owner.all
end
def new
@owner = Owner.new
end
def create
@owner = Owner.new(owner_params)
if @owner.valid?
@owner.save
redirect_to owner_path(@owner)
else
render :new
end
end
def show
@owner = Owner.find(params[:id])
end
def edit
@owner = Owner.find(params[:id])
end
def update
@owner = Owner.find(params[:id])
if @owner.update(owner_params)
redirect_to owner_path(@owner)
else
render :edit
end
end
def destroy
@owner = Owner.find(params[:id])
@owner.destroy
redirect_to owners_path
end
private
def
owner_params
params.require(:owner).permit(:first_name, :last_name, :age, :email)
end
end

This might look a bit intimidating, but once we go over each action, you will be able to understand the whole picture!

def index
@owners = Owner.all
end
def new
@owner = Owner.new
end

When writing your index.html.erb file for your index page, you will typically want to iterate over all the owners to have a list of them in your index page. In order to do that, you will need the instance of owners to follow through to your view page. The same concept will apply for the new.html.erb file.

private
def owner_params
params.require(:owner).permit(:first_name, :last_name, :age, :email)
end

This private params method is added for best security practices. With strong params, the developer can control which attributes the user is permitted to create or update. In this case, the user will be able to create and update the aforementioned attributes.

def create
@owner = Owner.new(owner_params)
if @owner.valid?
@owner.save
redirect_to owner_path(@owner)
else
render :new
end
end
def update
@owner = Owner.find(params[:id])
if @owner.update(owner_params)
redirect_to owner_path(@owner)
else
render :edit
end
end

The create and update methods are similar methods, but the create method will create a new user using the permitted strong params and check to see if there are any set validations. Validations can be written in your models as such:

validates :first_name, presence :true

The valid? code will go back to the associated model, check to see if there are any restrictions the user must abide by (i.e. the first_name field must contain something), and if the following validations are met, the owner will be saved and redirected to the owner_path(@owner), which is the show path. If you look back to your routes page, this is the shorthand way to write out the path without having to explicitly state “/owners/:id”. In this case, we want to redirect the user to the specified :id of the owner created at that instance, so we pass through an argument of that @owner. If the @owner is not valid or saved/created, the user will be rendered the specific view file. The same applies to the update method.

def destroy
@owner = Owner.find(params[:id])
@owner.destroy
redirect_to owners_path
end

Finally, the destroy method will find the owner with the params of :id and destroy the instance. Because the owner no longer exists, the user should be redirected to a page in which the user does exist, which is the owners_path, the index.

When to use redirect_to and render

If you’ve gotten this far, the way models, controllers, and views work should be familiar to you. Most of the routes are primarily used within the controller to redirect_to and render pages. The difference between the two is that redirect_to will redirect the user to a certain URL by telling the browser to make a new request to a different location, whereas render will call the template named without the need to specifically redirect the user. For example, if a user wants to create a new username on a social media platform, the user should be directed to a URL looking something like this:

https://socialmedia.com/new

If the user enters information that is invalid, such as forgetting to put an e-mail address, the same form should be rendered so that the user can fill out his or her information again, not changing the URL. Otherwise, the user should be redirected to the next page, which would typically be the users personal account page, as such:

https://socialmedia.com/jennsaccount
This would, of course, be unique to each user.

Sources:

--

--