我环顾四周如何更改动态params插槽,发现这篇文章确实完成了。 帖子是http://robots.thoughtbot.com/post/159809070/rails-patch-change-the-name-of-the-id-parameter-in
基本上它的作用是,如果以下是路线:
map.resources :clients, :key => :client_name do |client|
client.resources :sites, :key => :name do |site|
site.resources :articles, :key => :title
end
end
这些路线创建以下路径:
/clients/:client_name
/clients/:client_name/sites/:name
/clients/:client_name/sites/:site_name/articles/:title
一种解决方案是覆盖模型中的def to_param
方法,但我希望这样做而不触及模型本身。
但是因为它的Rails 2.x,我如何才能为Rails 3实现相同的目标?
更新
此应用正在使用Mongoid。不是AR。 因此,友好的宝石不能用于afaik。
答案 0 :(得分:176)
在Rails 4中,添加了:param
选项,这似乎完全符合您的要求。您可以查看与Rails 3 code相比较的Rails 4 code。
您可以在routes.rb
文件中轻松实现此目的:
# config/routes.rb
resources :posts, param: :slug
# app/controllers/posts_controller.rb
# ...
@post = Post.find_by(slug: params[:slug])
# ...
自Rails 4发布以来,此功能为documented in the Rails Guides。
不幸的是,在Rails 3中,:key
的{{1}}选项已被删除,因此您无法再通过传入额外选项轻松更改以此方式创建的路由的名称。
我假设你已经以某种方式让应用程序在过去的一年中以你想要的方式运行,但是我将在resources
中找到你在Rails 3中描述的效果。它只需要比routes.rb
方法更多的工作。您仍然可以使用to_param
和scope
(或者它的堂兄match
,get
,put
和post
)定义的路线中定义自定义参数。您只需在匹配器中写入所需的参数名称:
delete
您必须手动添加get 'clients/:client_name', :to => 'clients#show', :as => client
scope 'clients/:client_name' do
get 'sites/:name', :to => 'sites#show', :as => site
end
自动为您创建的所有路线,但它可以实现您正在寻找的路线。您还可以有效地使用resources
选项和:controller
以及其他scope
块来取消部分重复。
EDIT(2014年5月8日):让答案更明显,答案包含Rails 3& 4.更新代码的链接以转到确切的行号和提交,以便它们可以工作更长的时间。
EDIT(2014年11月16日): Rails 4现在应该位于顶部并包含相关信息,因为它已经是Rails的当前版本已经有一段时间了。
EDIT(2016年8月9日):反映该解决方案仍可在Rails 5中运行,并更新过时的链接。
答案 1 :(得分:41)
在Rails 4中,传递param选项来更改:id参数。例如
resources :photos, param: :photo_name
会生成/ photos /:photo_name
答案 2 :(得分:1)
如果我理解正确,您想要的是在您的网址中设置client_name
而不是id
,对吗?
您可以通过覆盖模型中的to_param
方法来实现。您可以获得更多信息here。
答案 3 :(得分:1)
有一个宝石,就像有一切宝石一样;)
我一直在使用FriendlyId来处理rails 3中的这种行为。
这需要您为模型添加一些代码,例如:
class Client < ActiveRecord::Base
has_friendly_id :name
end
...如果您的客户端没有URI兼容的名称,您可能希望使用slug,您可以使用has_friendly_id :name, :use_slug => true
。使用slugs时,你显然需要将它们持久存储到数据库中。
如前所述,您仍然可以使用rails to_param
技巧,如文档here所述。我觉得FriendlyId有点多才多艺。
答案 4 :(得分:0)
在Rails 3中,您可以使用以下命名空间和范围的组合来重命名id密钥(虽然不是很好):
namespace :clients do
scope "/:client_name" do
namespace :sites do
scope "/:name" do
post "/:title" => "articles#create"
...
end
end
end
end