Routing is an important component of the Ruby on Rails framework. Here are a few essential routing concepts, compiled from Obie Fernandez’s excellent book “The Rails 5 Way”, as well as the official Rails documentation on routing.
Primarily, routing does two things:
- Maps requests to controller action methods.
- Enables the dynamic generation of URLs for you to use as arguments to methods like
link_to
andredirect_to
to generate proper HTML links.
Routes are defined in config/routes.rb
file, generated when you bootstrap a Rails app.
Rails.application.routes.draw do
# get "URL pattern", to: "controller/action"
# get "URL pattern" => "controller/action"
get "products/:id" => "products#show"
end
Routes are checked in the order they are defined in the routes.rb
file. The search ends as soon as a match is found.
Redirect routes
get "/foo", to: redirect("/bar")
Root
The root route specifies what should happen when someone navigates to the ‘root’ of your application.
root to: "welcome#index"
root to: "home#index"
Named Routes
When you name a route, two new methods get defined for use in your controllers and views.
name_url
: returns a URL string that will trigger the routename_path
: returns the path part of the URL (relative URL) without the protocol and host.
get "help" => "help#show", as: "help"
# help_url : https://railsapp.com/help
# help_path : /help
Using named routes, you can simplify the following code:
link_to "Auction of #{item.name}",
controller: "items",
action: "show",
id: item.id
to something simple:
link_to "Auction of #{item.name}", item_path(id: item.id)
This assumes you have a named route defined as follows:
get "item/:id" => "items#show", as: "item"
Scoped Routes
Rails allows you to bundle together related routing rules using scoped routes. For example, you can replace the following routing code
get "auctions/new" => "auctions#new"
get "auctions/edit/:id" => "auctions#edit"
post "auctions/pause/:id" => "auctions#pause"
with the following code that uses scoped routes.
scope controller: :auctions do
get "auctions/new" => :new
get "auctions/edit/:id" => :edit
post "auctions/pause/:id" => :pause
end
you can further dry up the above code by using the :path
argument to scope.
scope path: "/auctions", controller: :auctions do
get "new" => :new
get "edit/:id" => :edit
post "pause/:id" => :pause
end
Furthermore, the scope
method can interpret a symbol (if it’s the first argument) as a controller. So you could just say:
scope :auctions, path: "/auctions" do
end
Finally, you can use the controller
method instead of the scope
method.
controller :auctions do
end
Resource Routing
Quickly declare all the common routes for a resource. It generates the routes for index
, show
, new
, create
, edit
, update
, and destroy
actions. For example, a single entry in the routing file, such as:
resource :photos
creates the following routes for your app, all mapping to the Photos controller.
HTTP Verb | Path | Controller#Action | Used For |
---|---|---|---|
GET | /photos | photos#index | display a list of all photos |
GET | /photos/new | photos#new | HTML form for creating new photo |
POST | /photos | photos#create | create a new photo |
GET | /photos/:id | photos#show | display a photo with the given id |
GET | /photos/:id/edit | photos#edit | HTML form for editing the photo |
PATCH/PUT | /photos/:id | photos#update | update a specific photo |
DELETE | /photos/:id | photos#destroy | delete a specific photo |
You can also create multiple resources in the same line.
resources :photos, :books, :videos