In Rails 4, the :param
option was added, which seems to do exactly what you're looking for. You can take a look at the Rails 3 code compared to the Rails 4 code.
You can easily implement this in your routes.rb
file:
# config/routes.rb
resources :posts, param: :slug
# app/controllers/posts_controller.rb
# ...
@post = Post.find_by(slug: params[:slug])
# ...
As of the release of Rails 4, this functionality is documented in the Rails Guides.
Unfortunately, in Rails 3, the :key
option for resources
was removed, so you can no longer easily change the name for routes created in this way by just passing in an extra option.
I assume you've already somehow gotten the application working the way you want in the past year, but I will go into a way to get the effect you describe in Rails 3 in routes.rb
. It will just involve a bit more work than the to_param
method. You can still define custom parameters in routes defined using scope
and match
(or it's cousins get
, put
, post
, and delete
). You simply write in the parameter name you want in the matcher:
get 'clients/:client_name', :to => 'clients#show', :as => client
scope 'clients/:client_name' do
get 'sites/:name', :to => 'sites#show', :as => site
end
You would have to manually add all the routes that resources
automatically creates for you, but it would achieve what you're looking for. You could also effectively use the :controller
option with scope
and additional scope
blocks to take out some of the repetition.
EDIT (May 8, 2014): Make it more obvious the answer contains information for both Rails 3 & 4. Update the links to the code to go to exact line numbers and commits so that they should work for a longer period of time.
EDIT (Nov 16, 2014): Rails 4 should be at the top now and include relevant information as it's been the current version of Rails for quite some time now.
EDIT (Aug 9, 2016): Reflect that the solution still works in Rails 5, and update outdated links.
in Rails 4, pass param option to change the :id params. For example
resources :photos, param: :photo_name
will generate /photos/:photo_name
In Rails 3 you can rename the id keys by using a combination of namespaces and scopes like this (not very nice though):
namespace :clients do
scope "/:client_name" do
namespace :sites do
scope "/:name" do
post "/:title" => "articles#create"
...
end
end
end
end
If I understand you correctly, what you want is to have the client_name
instead of id
in your url, right?
You can do that by overriding the to_param
method in your model. You can get more information here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With