11
votes

I am looking to use link_to to call a method in my controller. However, for some odd reason the route looks for the show method.

In my view:

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

In my config/routes.rb

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

In my 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

When I click on the archive link in the view, the URL does change to: http://localhost:3000/beverages/archive?id=11, however I get the following error.

The error I get: error ActiveRecord::RecordNotFound (Couldn't find Beverage with id=archive): app/controllers/beverages_controller.rb:46:in `show'

Any idea on what I am doing wrong? Your help is much appreciated!

PS. I also looked at Rails 3 link_to delete destory method calls show method? but nothing seemed to work.

3
Could you show your routes.rb? Probably you have something like resources :beverages above match line? - dimuch

3 Answers

9
votes

Have you tried this in your routes?

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

This will create the beverages_archive_path method for you. Also, as you are looking for a specific beverage, use :id inside the route so that it knows where to take the id parameter from.

Apart from that, you can always tell a link specifically which controller and action to link to by doing:

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

Taken from here: Ruby on rails 3 link_to controller and action

5
votes

Use the other notation (not match) instead.

resources :beverages do
  collection do
    get :archive
  end
 end

Try this one out and let me know if something went wrong.

0
votes

There's not quite enough information here to know why beverages_archive_path works in your app -- one problem is that your routes file does not define a name for your beverages#archive route. What you want is something like:

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

or better yet use resourceful routing conventions like so:

resources :beverages do
  collection do
    get :archive
  end
end

What's happening is that you have a beverages#show route that matches /beverages/:id, and this is what /beverages/archive matches (with :id => 'archive').