Rails: пользовательские действия вложенного контроллера

Я хочу настроить пользовательский вложенный контроллер действий, но я не могу понять, маршрутизация.

Я продолжаю получать следующую ошибку

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 ответа

Решение

Есть несколько проблем: маршрутизация на accept действие и создание URL для вложенного ресурса.

Определение пользовательских действий

Вы можете добавить пользовательские действия к своим ресурсам RESTful, используя этот синтаксис:

resources :requests do
  get 'accept', :on => :member
end

Это даст вам маршрут, который выглядит следующим образом:

requests/:id/accept

И вы можете генерировать пути в ваших представлениях, используя:

accept_request_path(a_request)

:on => :member part указывает, что вы направляетесь к новому действию для каждого отдельного запроса, а не к сбору всех запросов. Если вы использовали :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) %>

Подходящие глаголы

Accept звучит очень похоже на то, что каким-то образом обновляет вашу базу данных, и если это так, вам следует рассмотреть возможность использования PUT запрос, а не GET запрос.

Спецификация HTTP/1.1 гласит, что было установлено, что методы GET и HEAD НЕ ДОЛЖНЫ иметь значение, кроме выполнения поиска ( RFC2616, раздел 9), который имеет реальное значение, что не-человеческие веб-клиенты - индексаторы поисковых систем, расширения браузера и т. д. - разрешено переходить по ссылкам (которые делают 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 %>

Больше документации

В вашем файле маршрута:

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

и ввиду

link_to "Accept", accept_path(request) 
Другие вопросы по тегам