Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
333 views
in Technique[技术] by (71.8m points)

ruby - Change the name of the :id parameter in Routing resources for Rails

I looked around on how to change the dynamic params slot and found this post that does the exact thing. The post is https://thoughtbot.com/blog/rails-patch-change-the-name-of-the-id-parameter-in

Basically what it does is, if following is the routes:

map.resources :clients, :key => :client_name do |client|
  client.resources :sites, :key => :name do |site|
    site.resources :articles, :key => :title
  end
end

These routes create the following paths:

/clients/:client_name
/clients/:client_name/sites/:name
/clients/:client_name/sites/:site_name/articles/:title

One solution is to override the def to_param method in the model, but I want this without touching the model itself.

But since its for Rails 2.x, how can I achieve the same for Rails 3?

Update

This app is using Mongoid. Not AR. So, the gem friendly cannot be used afaik.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Rails 4 & 5

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.

Details

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.

Rails 3

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.

Details

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...