Posted 2 months ago. Visible to the public. Linked content. Auto-destruct in 5 days

Updated: Rails routes: Extracting collection actions into their own controllers

In modern Rails versions we can define nested resources in a collection { ... } block to namespace them into an existing resource:

resources :projects, only: :show do collection do resource :report, only: :show, controller: 'projects/report' resources :members, only: [:index, :show] end end

This generates the following routes:

GET /projects/:id => ProjectsController#show GET /projects/report => Projects::ReportsController#show GET /projects/members => MembersController#index GET /projects/members/:id => MembersController#show

Note how /projects/report, /projects/members and /projects/members/:id do not take a :project_id.


Take care when defining nested resources, as they don't behave identical to namespaced resources:

namespace :users do resources :sign_ups, only: [:new] end # GET /users/sign_ups/new => Users::SignUpsController#new
resources :users, only [] do resources :sign_ups, only: [:new] end # GET /users/sign_ups/new => SignUpsController#new

Both solutions will generate the same routes, the controller paths will be different, though. In the first example rails will expect to find a Users::SignUpsController in the subdirectory controllers/users/sign_ups_controller.rb, but there has to be a SignUpsController in controllers/sign_ups_controller.rb in order to make the second example work.
You can alter this behaviour with a custom controller path, as shown in the very first example of this card (resource :report, only: :show, controller: 'projects/report').

makandra has been working exclusively with Ruby on Rails since 2007. Our laser focus on a single technology has made us a leader in this space.

Owner of this card:

Henning Koch
Last edit:
about 1 month ago
by Jakob Scholz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more