在路由资源中为Rails更改:id参数的名称

时间:2011-07-06 05:43:39

标签: ruby-on-rails ruby ruby-on-rails-3

我环顾四周如何更改动态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。

5 个答案:

答案 0 :(得分:176)

Rails 4& 5

在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

不幸的是,在Rails 3中,:key的{​​{1}}选项已被删除,因此您无法再通过传入额外选项轻松更改以此方式创建的路由的名称。

详细信息

我假设你已经以某种方式让应用程序在过去的一年中以你想要的方式运行,但是我将在resources中找到你在Rails 3中描述的效果。它只需要比routes.rb方法更多的工作。您仍然可以使用to_paramscope(或者它的堂兄matchgetputpost)定义的路线中定义自定义参数。您只需在匹配器中写入所需的参数名称:

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