Rails:自定义嵌套控制器操作

时间:2012-06-30 09:32:57

标签: ruby-on-rails custom-action nested-routes controller-action

我想设置自定义嵌套控制器操作,但我无法弄清楚路由。

我一直收到以下错误

No route matches [GET] "/assets"

的routes.rb

resources :companies do
  resources :requests do
    match :accept
  end
end

index.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 %>

2 个答案:

答案 0 :(得分:24)

存在以下几个问题:路由到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_idid

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, section 9)现实世界的含义是,非人类网络客户端 - 搜索引擎索引器,浏览器扩展等 - 可以跟随链接(发出GET个请求),但不允许提交发出其他类型请求的表单。< / p>

如果您切换到使用PUT请求,那么button_to helper就会派上用场。与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 %>

更多文档

答案 1 :(得分:2)

路径文件中的

match 'request/accept/:id' => 'requests#accept', :as => :accept

并在视野中

link_to "Accept", accept_path(request)