如何将自定义 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
操作视为类的实例方法。它始终适用于现有资源。
默认成员操作:show
、edit
、update
、destroy
:collection
操作
:collection
操作的 URL 不包含目标资源的 ID。例如:
users/login
users/register
您可以将:collection
操作视为类的静态方法。
默认收集操作:index
、new
、create
在您的情况下,您需要两个新的注册操作。这些操作属于 :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 => :validate => :get
吗? hash
参数如何插入?
更新了我的答案,看看吧。
什么告诉confirm_user_path
使用@user.confirmation_code
代替:id
通配符而不是@user.foo
或@user.bar
?这应该是confirm_user_path(:id => @user.confirmation_code)
吗?
@KandadaBoggu,请注意:*** 说我可以在 4 小时内发放赏金 :)
是的,你必须使用confirm_user_path(:id => @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】:如果我正确理解您的问题,您只想重命名 new
和 create
操作的网址。
这将是这样完成的:
map.resources :users, :path_names => :new => 'signup', :create => 'register'
如果您真的想添加带有相应控制器操作的新路由,那么 Damiens 的答案就是您要走的路。
【讨论】:
@mikezter,我肯定还需要new
和create
路线。但是,这回答了我对过去的重命名路线的疑问。谢谢:)【参考方案4】:
new
选项允许您创建用于创建新对象的新路由。这就是为什么它们以该术语为前缀。
您正在寻找的是:collection
选项。
map.resources :users, :collection => :signup => :get, :register => :post
这将创建 /users/signup
和 /users/register
网址。
【讨论】:
我很难理解collection
的用途。 is 路径用于创建新对象;注册的访问者创建一个新的User
对象。那么,我为什么不想使用new
?这是 Rails 指南中的错字吗?以上是关于如何将自定义 RESTful 路由添加到 Rails 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章
将自定义中间件添加到 Laravel Passport 端点