Rails provides several ways to organize your routes.
Scope by URL:
scope 'admin' do
get 'dashboard', to: 'administration#dashboard'
resources 'employees'
end
This generates the following routes
get '/admin/dashboard', to: 'administration#dashboard'
post '/admin/employees', to: 'employees#create'
get '/admin/employees/new', to: 'employees#new'
get '/admin/employees/:id/edit', to: 'employees#edit'
get '/admin/employees/:id', to: 'employees#show'
patch/put '/admin/employees/:id', to: 'employees#update'
delete '/admin/employees/:id', to: 'employees#destroy'
It may make more sense, on the server side, to keep some views in a different subfolder, to separate admin views from user views.
Scope by module
scope module: :admin do
get 'dashboard', to: 'administration#dashboard'
end
module
looks for the controller files under the subfolder of the given name
get '/dashboard', to: 'admin/administration#dashboard'
You can rename the path helpers prefix by adding an as
parameter
scope 'admin', as: :administration do
get 'dashboard'
end
# => administration_dashboard_path
Rails provides a convenient way to do all the above, using the namespace
method. The following declarations are equivalent
namespace :admin do
end
scope 'admin', module: :admin, as: :admin
Scope by controller
scope controller: :management do
get 'dashboard'
get 'performance'
end
This generate these routes
get '/dashboard', to: 'management#dashboard'
get '/performance', to: 'management#performance'
Shallow Nesting
Resource routes accept a :shallow
option that helps to shorten URLs where possible. Resources shouldn't be nested more than one level deep. One way to avoid this is by creating shallow routes. The goal is to leave off parent collection URL segments where they are not needed. The end result is that the only nested routes generated are for the :index
, :create
, and :new
actions. The rest are kept in their own shallow URL context. There are two options for scope to custom shallow routes:
:shallow_path: Prefixes member paths with a specified parameter
scope shallow_path: "sekret" do
resources :articles do
resources :comments, shallow: true
end
end
:shallow_prefix: Add specified parameters to named helpers
scope shallow_prefix: "sekret" do
resources :articles do
resources :comments, shallow: true
end
end
We can also illustrate shallow
routes more by:
resources :auctions, shallow: true do
resources :bids do
resources :comments
end
end
alternatively coded as follows (if you’re block-happy):
resources :auctions do
shallow do
resources :bids do
resources :comments
end
end
end
The resulting routes are:
Prefix | Verb | URI Pattern |
---|---|---|
bid_comments | GET | /bids/:bid_id/comments(.:format) |
POST | /bids/:bid_id/comments(.:format) | |
new_bid_comment | GET | /bids/:bid_id/comments/new(.:format) |
edit_comment | GET | /comments/:id/edit(.:format) |
comment | GET | /comments/:id(.:format) |
PATCH | /comments/:id(.:format) | |
PUT | /comments/:id(.:format) | |
DELETE | /comments/:id(.:format) | |
auction_bids | GET | /auctions/:auction_id/bids(.:format) |
POST | /auctions/:auction_id/bids(.:format) | |
new_auction_bid | GET | /auctions/:auction_id/bids/new(.:format) |
edit_bid | GET | /bids/:id/edit(.:format) |
bid | GET | /bids/:id(.:format) |
PATCH | /bids/:id(.:format) | |
PUT | /bids/:id(.:format) | |
DELETE | /bids/:id(.:format) | |
auctions | GET | /auctions(.:format) |
POST | /auctions(.:format) | |
new_auction | GET | /auctions/new(.:format) |
edit_auction | GET | /auctions/:id/edit(.:format) |
auction | GET | /auctions/:id(.:format) |
PATCH | /auctions/:id(.:format) | |
PUT | /auctions/:id(.:format) | |
DELETE | /auctions/:id(.:format) |
If you analyze the routes generated carefully, you’ll notice that the nested parts of the URL are only included when they are needed to determine what data to display.