Rails: link_to вызывает пользовательский метод в контроллере

Я хочу использовать link_to для вызова метода в моем контроллере. Однако по какой-то нечетной причине маршрут ищет метод show.

На мой взгляд:

<% @beverages.each do |beverage| %>
    ..
    <%= link_to 'Archive', beverages_archive_path(:id => beverage.id) %>
    ..
<% end %>

В моей конфигурации /routes.rb

match 'beverages/archive' => 'beverages#archive'

В моем beverages_controller.rb

  def archive
    beverage = Beverage.find(params[:id])

    respond_to do |format|
    #  format.html # show.html.erb
      format.json { render json: beverage }
    end
    # beverage.update_attribute('archive', true)
  end

Когда я нажимаю ссылку на архив в представлении, URL-адрес меняется на: http://localhost:3000/beverages/archive?id=11, однако я получаю следующую ошибку.

Ошибка, которую я получаю: error ActiveRecord:: RecordNotFound (Не удалось найти напиток с id = archive): app/controllers/beverages_controller.rb: 46: в `show '

Любая идея о том, что я делаю неправильно? Ваша помощь очень ценится!

PS. Я также посмотрел на Rails 3 link_to удалить метод вызова метода вызова метод show? но ничего не работало.

Ответ 1

Вы пробовали это на своих маршрутах?

match 'beverages/:id/archive' => 'beverages#archive', as: :beverages_archive

Это создаст для вас метод beverages_archive_path. Кроме того, поскольку вы ищете определенный напиток, используйте: id внутри маршрута, чтобы он знал, откуда взять параметр id.

Кроме того, вы всегда можете указать ссылку, с которой связан контроллер и действие:

link_to "Label", :controller => :my_controller, :action => :index

Взято отсюда: Ruby on rails 3 link_to контроллер и действие

Ответ 2

Вместо этого используйте другую нотацию (не match).

resources :beverages do
  collection do
    get :archive
  end
 end

Попробуй это и дайте мне знать, если что-то пошло не так.

Ответ 3

Здесь не достаточно информации, чтобы знать, почему beverages_archive_path работает в вашем приложении - одна проблема заключается в том, что ваш файл маршрутов не определяет имя для вашего маршрута beverages#archive. То, что вы хотите, это что-то вроде:

match 'beverages/archive' => 'beverages#archive', :as => :beverages_archive

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

resources :beverages do
  collection do
    get :archive
  end
end

Что происходит в том, что у вас есть маршрут beverages#show, который соответствует /beverages/:id, и это соответствует /beverages/archive:id => 'archive').