Overriding Named Route Parameters in Rails
Rails will use :id
as the default parameter in resourceful routes.
resources :products
This gives us the following routes:
Prefix Verb URI Pattern Controller#Action
products GET /products(.:format) products#index
POST /products(.:format) products#create
new_product GET /products/new(.:format) products#new
edit_product GET /products/:id/edit(.:format) products#edit
product GET /products/:id(.:format) products#show
PATCH /products/:id(.:format) products#update
PUT /products/:id(.:format) products#update
DELETE /products/:id(.:format) products#destroy
But what if we aren’t looking up products by :id
? We might want to look up products using a SEO-friendly permalink, or perhaps by using some token. You can obviously still pass that value as the id
, but this can easily lead to confusion.
A better way is to specify the parameter.
resources :products, param: :permalink
This gives us the following routes:
Prefix Verb URI Pattern Controller#Action
products GET /products(.:format) products#index
POST /products(.:format) products#create
new_product GET /products/new(.:format) products#new
edit_product GET /products/:permalink/edit(.:format) products#edit
product GET /products/:permalink(.:format) products#show
PATCH /products/:permalink(.:format) products#update
PUT /products/:permalink(.:format) products#update
DELETE /products/:permalink(.:format) products#destroy
The only sucky part is that Rails won’t automatically do the right thing when using link_to
. So doing link_to @product
will still generate a link using the product’s id
. If you want to change that you can override the to_param
method on your model.
class Product < ActiveRecord::Base
def to_param
permalink
end
end
Happy coding.