Nested Route Parameters in Rails
The Rails routing configuration allows you override the named parameters in your routes.
resources :products, only: :show, param: :sku
This generates a path that looks like this:
Prefix Verb URI Pattern Controller#Action
product GET /products/:sku(.:format) products#show
However, it doesn’t work in certain scenarios. For example, I often find myself wanting to do something like this:
namespace :api do
resources :products, only: [], param: :legacy_id do
resources :events, only: :create, controller: 'product_events'
end
end
Which generates the following path:
Prefix Verb URI Pattern Controller#Action
api_product_events POST /api/products/:product_legacy_id/events(.:format) api/product_events#create
It gets akward having to reference params[:product_legacy_id]
in your controller, especially if you’ve standardized on variables like legacy_product_id
(which reads and sounds better). So how do we specify the parameter in nested routes? We can choose to forego the resources
helper:
post '/api/products/:legacy_product_id/events', to: 'product_events#create', as: 'api_product_events'
But this gets tedious and is more error-prone. A better way - in my opinion - is to use nesting with the member
helper.
namespace :api do
resources :products, only: [], param: :legacy_product_id do
member do
resources :events, only: :create, controller: 'product_events', as: 'product_events'
end
end
end
Which generates the path that I want:
Prefix Verb URI Pattern Controller#Action
api_product_events POST /api/products/:legacy_product_id/events(.:format) api/product_events#create