I want to setup a custom nested controller actions but I can't figure out the routing.
I keep getting the following error
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 %>
There are a couple of problems: routing to the accept
action and building a URL to a nested resource.
You can add custom actions to your RESTful resources using this syntax:
resources :requests do
get 'accept', :on => :member
end
This will give you a route that looks like this:
requests/:id/accept
And you can generate paths in your views using:
accept_request_path(a_request)
The :on => :member
part indicates that you're routing to a new action on each individual request, rather than the collection of all requests. If you used :on => :collection
the route would be requests/accept
When you nest resources:
resources :companies do
resources :requests do
get 'accept', :on => :member
end
end
You get routes that look like this, note that because the requests is nested inside companies the route includes both a company_id
and an id
:
companies/:company_id/requests/:id/accept
And helpers like this:
accept_company_request_path(a_company, a_request)
You could do this long-hand, as you're currently trying to do, with something like:
<%= link_to "Accept",
:controller => "requests", :action => "accept",
:id => request.id, :company_id => request.company.id %>
But it's easier to use the helpers:
<%= link_to "Accept", accept_company_request_path(request.company, request) %>
Accept sounds a lot like something that updates your database in some way, and if that's the case you should consider using a PUT
request rather than a GET
request.
The HTTP/1.1 spec says that the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval ( RFC2616, section 9 ) which has the real-world implication that non-human web clients — search engine indexers, browser extensions, etc. — are allowed to follow links (which make GET
requests) but not allowed to submit forms that make other types of requests.
If you do switch to using a PUT
request then the button_to
helper will come in handy. As with link_to
you can pass the controller, action, method, and all the parameters required by the route to button_to
:
<%= button_to 'Accept',
{:controller => :requests, :action => :accept,
:company_id => request.company, :id => request},
:method => :put %>
Or you can use the helpers to generate the path which is much easier:
<%= button_to 'Accept',
accept_company_request_path(request.company, request),
:method => :put %>
in your route file:
match 'request/accept/:id' => 'requests#accept', :as => :accept
and in view
link_to "Accept", accept_path(request)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.