【问题标题】:Change the name of the :id parameter in Routing resources for Rails在 Rails 的路由资源中更改 :id 参数的名称
【发布时间】:2011-09-29 08:10:02
【问题描述】:

我查看了如何更改动态参数槽,发现这篇文章确实可以做到这一点。 帖子是https://thoughtbot.com/blog/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。

【问题讨论】:

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


    【解决方案1】:

    导轨 4 和 5

    在 Rails 4 中,添加了 :param 选项,这似乎完全符合您的要求。您可以看看Rails 3 codeRails 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

    导轨 3

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

    详情

    我假设您在过去一年中已经以某种方式使应用程序按照您想要的方式运行,但我将介绍一种方法来获得您在 routes.rb 中在 Rails 3 中描述的效果。它只涉及比to_param 方法更多的工作。您仍然可以在使用scopematch(或者它的表亲getputpostdelete)定义的路由中定义自定义参数。您只需在匹配器中写入您想要的参数名称:

    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 和其他 scope 块一起使用,以消除一些重复。


    编辑(2014 年 5 月 8 日): 让答案更明显地包含 Rails 3 和 4 的信息。更新代码链接以转到确切的行号和提交,以便它们应该可以工作更长的时间。

    编辑(2014 年 11 月 16 日):Rails 4 现在应该在顶部,并且包含相关信息,因为它已经是 Rails 的当前版本已有一段时间了。

    编辑(2016 年 8 月 9 日):反映该解决方案在 Rails 5 中仍然有效,并更新过时的链接。

    【讨论】:

    • 所以基本上,Rails3 在路由器中创建了资源选项以使其保持完整,但为了拥有自定义变量名称,需要覆盖......感觉很蹩脚!
    • 这是 rails 3 的 param 选项的反向移植:gist.github.com/sj26/44ef47fe8b98b46ee32d
    • 这最终破坏了 url 助手。如果我传入一个对象,他们最终会生成一个正常的基于 id 的路由,或者如果我传入 slug 则抱怨缺少 [:slug] 键。有什么解决方法的想法吗?
    • 仅供参考,如果您使用嵌套资源,则父资源的参数将为 post_slug,这可能会造成混淆。
    • 这确实很好,但是如果我不希望嵌套资源的父 ID 的参数名称(如 post_post_id),我该怎么办?
    【解决方案2】:

    在 Rails 4 中,通过 param 选项更改 :id 参数。例如 resources :photos, param: :photo_name 会生成 /photos/:photo_name

    【讨论】:

      【解决方案3】:

      在 Rails 3 中,您可以像这样使用命名空间和范围的组合来重命名 id 键(虽然不是很好):

      namespace :clients do
        scope "/:client_name" do
          namespace :sites do
            scope "/:name" do
               post "/:title" => "articles#create"
               ...
            end
          end
        end
      end
      

      【讨论】:

        【解决方案4】:

        如果我对您的理解正确,您希望在您的网址中使用client_name 而不是id,对吗?

        您可以通过覆盖模型中的 to_param 方法来做到这一点。您可以通过here获取更多信息。

        【讨论】:

        • 正如我已经提到的,我有不改变模型的约束。 Rails 3 中是否不支持或弃用上述示例?
        【解决方案5】:

        这有一颗宝石,就像所有事物都有一颗宝石;)

        我一直在使用 FriendlyId 来处理 rails 3 中的这种行为。

        不过,这需要您向模型中添加一些代码,如下所示:

        class Client < ActiveRecord::Base
          has_friendly_id :name
        end
        

        ...如果您的客户端没有与 URI 兼容的名称,您可能需要为此使用 slug,您可以使用 has_friendly_id :name, :use_slug =&gt; true 来实现。不过,在使用 slug 时,您显然还需要将它们持久化到数据库中。

        如前所述,您仍然可以将 to_param 技巧与 rails 3 一起使用,如 here 所记录的那样。不过,我发现 FriendlyId 用途更广泛。

        【讨论】:

        • 我喜欢友好的 id 并且在许多项目中使用过。实际上我的应用程序正在使用 Mongoid。而且friendly_id 不支持它。正如我已经提到的,我的约束是不改变模型。
        • 如果你使用 mongoid,有mongoid-slug 来实现这个功能。它实际上使用了to_param,但它也在后台做了一些其他聪明的事情。我在这里找到了链接:stackoverflow.com/questions/4744446/…
        • 我喜欢那颗宝石。还有另一个类似的slugoid。但正如我一直说的那样,我确实有不修改模型的限制。 to_param 破坏了我的应用程序的前端部分。实际上,我正在拼命寻找路由方法,即我必须更改我的 API,但不会破坏应用程序的模型和前端部分。为什么我不能只像我所说的那样只修改路线以及上面旧版本导轨的示例帖子???
        • 您是否尝试过重写您的控制器以使其使用您的自定义路由键?例如 @client = Client.find(:name =&gt; param[:client_name] in ClientsController#show ?这可能行得通。
        • Client.where(:name =&gt; param[:client_name]).first,即。
        猜你喜欢
        • 2015-08-19
        • 2014-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-29
        • 2012-04-07
        • 1970-01-01
        相关资源
        最近更新 更多