Routing in Rails

Brief introduction to Rails Routing

What exactly is routing?

When there's an HTTP request from the user to the application, it should be directed to the right controller. You can picture a router as a receptionist at who connects you to the right person to talk to.

routing-meme

How is routing done in Ruby on Rails?

In Rails, the routes of your application live in config/routes.rb. The Rails router recognises URLs and dispatches them to a controller's action. It can also generate paths and URLs, avoiding the need to hardcode strings in your views. Let's consider an application to book rooms in different Hotels and take a look at how this works.

Types of HTTP request methods

The application receives an HTTP request which carries along with it a method which could be:

GET - Retrieve a resource

POST - Create a resource

PUT - Completely update a resource

PATCH - Partially update a resource

DELETE - Delete a resource

These methods determine which controller action method is called.

Decoding the http request

If the application receives the request, GET /hotels/1. The request is dispatched to the hotels controller's show action with { id: '1' } in params.

get '/hotels/:id', to: 'hotels#show'

Similarly,

get '/hotels', to: 'hotels#index'
get '/hotels/:id', to: 'hotels#show'
get '/hotels/new', to: 'hotels#new'
post '/hotels', to: 'hotels#create'
get '/hotels/:id/edit', to: 'hotels#edit'
put '/hotels/:id', to: 'hotels#update'
delete '/hotels/:id', to: 'hotels#destroy'

TIP: If you ever want to list all the routes of your application you can use rails routes on your terminal and if you want to list routes of a specific resource, you can use rails routes | grep hotel. This will list all the routes of Hotel.

Defining resources

Like how the receptionist holds a record of all the reservations, the application too has its own record in config/routes.rb.

Rails.application.routes.draw do
  resources :hotels
end

By writing resources :hotels we create all seven different routes in your application, all mapping to the Hotels controller like mentioned above.

If your controller has only a few of these actions you can alter the same with the following keywords.

The keyword only includes only the actions mentioned. resources :hotels, only: [:edit]

There's also the keyword except to name the ones you don't want to include.

resources :hotels, except: [:index]

Single and multiple resources

Sometimes we have a single resource ie. we only have to access a single page instead of referencing an id. That's when we use singular term, resource.

resource :hotels

When you have to define multiple resources,

resources :hotels, :rooms which works the same as

resources :hotels,
resources :rooms

Nested Resources

Sometimes we have nested routes, /hotels/:id/rooms which are a result of resources that are logically children of other resources. For example, suppose your application includes these models:

class Hotel < ApplicationRecord
  has_many :rooms
end

class Room < ApplicationRecord
  belongs_to :hotel
end
nesting-meme

In which case we will declare our resources this way,

resources :hotels do
  resources :rooms
end

This declaration helps us access the nested URLs such as /hotels/:id/rooms , /hotels/:id/rooms/:id , /hotels/:id/rooms/new etc

Further Study

If you want to dig deeper into routing, you can refer to Rails Routing from the outside in http://guides.rubyonrails.org/routing.html.

Cover Photo by Javier Allegue Barros on Unsplash (https://unsplash.com/photos/C7B-ExXpOIE)