如何在Rails的map.resources()中重命名默认标识符param"id"?

new*_*ple 12 resources routes ruby-on-rails params

我喜欢Rail的map.resources生成的所有默认路由.但是,有些情况下我想在我的路线中使用非数字标识符.例如,如果嵌套路由由用户及其文章组成,则可以按如下方式编写标准路由:

map.resources :users, :has_many => [:articles] # => e.g. '/users/:id/articles/:id'
Run Code Online (Sandbox Code Playgroud)

但是,有许多优点/原因不使用Rails生成的默认数字标识符.有没有办法将default:id params替换为我选择的另一个规范标识符,而不会为每个标准操作编写自定义路由?如果我想要一个以下格式的路线:

'/users/:login/articles/:id'
Run Code Online (Sandbox Code Playgroud)

这种路线是否可以使用map.resources实现?

chr*_*isk 13

从Rails 2.3开始,无法更改参数名称并仍然使用#resources提供的自动路由.

作为解决方法,您可以articles使用:path_prefix和映射:name_prefix:

map.resources :articles, :path_prefix => "/users/:login",
                         :name_prefix => "user_"
Run Code Online (Sandbox Code Playgroud)

:path_prefix影响URL,以及:name_prefix影响产生的命名路由,所以你会与这些航线结束了:

    user_articles GET    /users/:login/articles(.:format)          {:controller=>"articles", :action=>"index"}
                  POST   /users/:login/articles(.:format)          {:controller=>"articles", :action=>"create"}
 new_user_article GET    /users/:login/articles/new(.:format)      {:controller=>"articles", :action=>"new"}
edit_user_article GET    /users/:login/articles/:id/edit(.:format) {:controller=>"articles", :action=>"edit"}
     user_article GET    /users/:login/articles/:id(.:format)      {:controller=>"articles", :action=>"show"}
                  PUT    /users/:login/articles/:id(.:format)      {:controller=>"articles", :action=>"update"}
                  DELETE /users/:login/articles/:id(.:format)      {:controller=>"articles", :action=>"destroy"}
Run Code Online (Sandbox Code Playgroud)

但是,作为一般的经验法则,我会坚持使用:user_id您在问题中发布的路由的Rails默认约定.通常理解:id并且:user_id不一定意味着"数字标识符" - 它们暗示"资源标识符",无论可能是什么.通过坚持默认约定,对于在Rails中使用资源路由的任何人来说,您的代码将更容易理解.

要为资源使用非数字标识符,只需#to_param在模型中重新定义即可.然后,确保在控制器中使用可通过此标识符(而不是数字ID)查找的查找程序,例如User#find_by_login!.


小智 12

您可以通过覆盖模型中的to_param来更改在URL中使用ID的默认值.例如

class User < ActiveRecord::Base
  def to_param
    login
  end
end

user_articles_path(@user) => "/users/:login/articles"
Run Code Online (Sandbox Code Playgroud)

您需要做的唯一其他更改是通过登录而不是控制器中的ID来查找用户.