如何将自定义 RESTful 路由添加到 Rails 应用程序?

Posted

技术标签:

【中文标题】如何将自定义 RESTful 路由添加到 Rails 应用程序?【英文标题】:How to add a custom RESTful route to a Rails app? 【发布时间】:2011-02-07 18:18:44 【问题描述】:

我正在读这两页

    resources Adding more RESTful actions

Rails 指南页面显示

map.resources :photos, :new =>  :upload => :post 

及其对应的网址

/photos/upload

这看起来很棒。


我的routes.rb 显示了这个

map.resources :users, :new =>  :signup => :get, :register => :post 

当我这样做时:[~/my_app]$ rake routes

我看到添加了两条新路线

  signup_new_user GET    /users/new/signup(.:format)
register_new_user POST   /users/new/register(.:format)

注意包含/new!我想要那个。我只想要/users/signup/users/register(如Rails 路由指南中所述)。

有什么帮助吗?

【问题讨论】:

【参考方案1】:

当您将控制器公开为资源时,会自动添加以下操作:

show
index
new
create
edit
update
destroy

这些操作可以分为两组:

:member 操作

成员操作的 URL 具有目标资源的 ID。例如:

users/1/edit 
users/1

您可以将:member 操作视为类的实例方法。它始终适用于现有资源。

默认成员操作:showeditupdatedestroy

:collection 操作

:collection 操作的 URL 不包含目标资源的 ID。例如:

users/login
users/register

您可以将:collection 操作视为类的静态方法。

默认收集操作:indexnewcreate

在您的情况下,您需要两个新的注册操作。这些操作属于 :collection 类型(因为您在提交这些操作时没有用户的 id)。您的路线可以如下:

map.resources :users, :collection =>  :signup => :get, :register => :post 

动作的网址如下:

users/signup
users/register

如果您想删除 Rails 生成的标准操作,请使用 :except/:only 选项:

map.resources :foo, :only => :show

map.resources :foo, :except => [:destroy, :show]

编辑 1

我通常将confirmation 操作视为:member 操作。在这种情况下,params[id] 将包含确认码。

路线配置:

map.resources :users, :member =>  :confirm => :get

网址

/users/xab3454a/confirm

confirm_user_path(:id => @user.confirmation_code) # returns the URL above

控制器

class UsersController < ApplicationController
  def confirm
    # assuming you have an attribute called `confirmation_code` in `users` table 
    # and you have added a uniq index on the column!!
    if User.find_by_confirmation_code(params[id])
      # success
    else
      # error
    end
  end
end

【讨论】:

@KandadaBoggu,这个解释看起来很棒。作为后续检查我的理解,假设我想在用户的欢迎电子邮件中发送“帐户确认”链接。该链接将包含一个 8 个字符的验证哈希。我要添加map.resources :users, :member =&gt; :validate =&gt; :get 吗? hash 参数如何插入? 更新了我的答案,看看吧。 什么告诉confirm_user_path 使用@user.confirmation_code 代替:id 通配符而不是@user.foo@user.bar?这应该是confirm_user_path(:id =&gt; @user.confirmation_code)吗? @KandadaBoggu,请注意:*** 说我可以在 4 小时内发放赏金 :) 是的,你必须使用confirm_user_path(:id =&gt; @user.confirmation_code),我会更新答案。【参考方案2】:

这可以看作是另一种语法——可能是一些值得了解的东西。

语法 1:

resources :users do
  member do
    get 'signup'
    post 'register'
  end
end

Rake Route 输出将包括

signup_users GET    /users/signup(.:format)    :action=>"signup", :controller=>"users"
register_users POST   /users/register(.:format)  :action=>"register", :controller=>"use

rs"

语法 2: 如果你只有一个收集路线

resources :users do
    get 'signup', :on => :collection
end

【讨论】:

我喜欢语法2,不错的遮阳篷【参考方案3】:

如果我正确理解您的问题,您只想重命名 newcreate 操作的网址。

这将是这样完成的:

map.resources :users, :path_names => :new => 'signup', :create => 'register'

如果您真的想添加带有相应控制器操作的新路由,那么 Damiens 的答案就是您要走的路。

【讨论】:

@mikezter,我肯定还需要newcreate 路线。但是,这回答了我对过去的重命名路线的疑问。谢谢:)【参考方案4】:

new 选项允许您创建用于创建新对象的新路由。这就是为什么它们以该术语为前缀。

您正在寻找的是:collection 选项。

map.resources :users, :collection =>  :signup => :get, :register => :post 

这将创建 /users/signup/users/register 网址。

【讨论】:

我很难理解collection 的用途。 is 路径用于创建新对象;注册的访问者创建一个新的User 对象。那么,我为什么不想使用new?这是 Rails 指南中的错字吗?

以上是关于如何将自定义 RESTful 路由添加到 Rails 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

Rails 路由:将自定义路由添加到标准操作列表

将自定义奏鸣曲页面路由添加到导航栏

将自定义路由添加到 Zend REST 控制器

将自定义中间件添加到 Laravel Passport 端点

如何将自定义挂钩添加到 Woocommerce 的自定义插件

如何将自定义事件添加到 jQuery 插件模式中