我想设置一个自定义嵌套控制器操作,但我无法弄清楚路由。
我不断收到以下错误
No route matches [GET] "/assets"
路线.rb
resources :companies do
resources :requests do
match :accept
end
end
索引.html.rb
<% @requests.each do |request| %>
<ul class="users">
<li>
<%= full_name(request.profile) %>
<%= request.status %>
<%= link_to "Accept",
:controller => "requests", :action => "accept",
:id => request.id %>
</li>
</ul>
<% end %>
有几个问题:路由到accept
操作和构建指向嵌套资源的 URL。
定义自定义操作
您可以使用以下语法将自定义操作添加到 RESTful 资源:
resources :requests do
get 'accept', :on => :member
end
这将为您提供如下所示的路线:
requests/:id/accept
您可以使用以下方法在视图中生成路径:
accept_request_path(a_request)
:on => :member
部分指示你正在路由到每个单独请求的新操作,而不是所有请求的集合。如果您使用:on => :collection
则路线将requests/accept
嵌套资源
嵌套资源时:
resources :companies do
resources :requests do
get 'accept', :on => :member
end
end
您得到的路由如下所示,请注意,由于请求嵌套在公司内部,因此路由包括company_id
和id
:
companies/:company_id/requests/:id/accept
像这样的助手:
accept_company_request_path(a_company, a_request)
你可以像你目前尝试的那样,用这样的方法做这个长手:
<%= link_to "Accept",
:controller => "requests", :action => "accept",
:id => request.id, :company_id => request.company.id %>
但是使用帮助程序更容易:
<%= link_to "Accept", accept_company_request_path(request.company, request) %>
适当的动词
接受听起来很像以某种方式更新数据库的东西,如果是这种情况,您应该考虑使用 PUT
请求而不是GET
请求。
HTTP/1.1 规范说,已经确立了约定,即 GET 和 HEAD 方法不应具有采取检索以外的操作的重要性(RFC2616,第 9 节),这在现实世界中意味着非人类 Web 客户端——搜索引擎索引器、浏览器扩展等——被允许跟踪链接(发出GET
请求),但不允许提交发出其他类型的请求的表单。
如果您确实切换到使用 PUT
请求,那么button_to
帮助程序将派上用场。与link_to
一样,您可以将控制器、操作、方法和路由所需的所有参数传递给button_to
:
<%= button_to 'Accept',
{:controller => :requests, :action => :accept,
:company_id => request.company, :id => request},
:method => :put %>
或者您可以使用帮助程序生成路径,这要容易得多:
<%= button_to 'Accept',
accept_company_request_path(request.company, request),
:method => :put %>
更多文档
- 添加更多 REST 操作
- 嵌套资源
文件中的
match 'request/accept/:id' => 'requests#accept', :as => :accept
并查看
link_to "Accept", accept_path(request)