Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails: link_to action, no route matches

I'm getting into Rails and trying to add a "vote" feature on a blog setup from here: http://guides.rubyonrails.org/getting_started.html

In app/controllers/posts_controller.rb I created this:

  def incvotes
    @post = Post.find(params[:id])
    post.update_attributes(:upvotes => 1 )
    format.html { redirect_to(@post, :notice => 'Vote counted.') }
    format.xml  { head :ok }
  end

In app/views/posts/index.html.erb I created this:

<%= link_to 'Vote', :controller => "posts", :action => "incvotes", :id => post.id %>

But the link is giving the error

No route matches {:controller=>"posts", :action=>"incvotes", :id=>1}

I'm missing something here, but not sure what.

rake routes:

incvotes_post POST   /posts/:id/incvotes(.:format) {:action=>"incvotes", :controller=>"posts"}
        posts GET    /posts(.:format)              {:action=>"index", :controller=>"posts"}
              POST   /posts(.:format)              {:action=>"create", :controller=>"posts"}
     new_post GET    /posts/new(.:format)          {:action=>"new", :controller=>"posts"}
    edit_post GET    /posts/:id/edit(.:format)     {:action=>"edit", :controller=>"posts"}
         post GET    /posts/:id(.:format)          {:action=>"show", :controller=>"posts"}
              PUT    /posts/:id(.:format)          {:action=>"update", :controller=>"posts"}
              DELETE /posts/:id(.:format)          {:action=>"destroy", :controller=>"posts"}
   home_index GET    /home/index(.:format)         {:action=>"index", :controller=>"home"}
         root        /(.:format)                   {:action=>"index", :controller=>"home"}
like image 589
Zeno Avatar asked May 18 '11 20:05

Zeno


3 Answers

try

= link_to "vote", incvotes_post_path(post), :method=>:post

and if that doesn't work, try changing the method to :put

like image 159
stephenmurdoch Avatar answered Nov 03 '22 21:11

stephenmurdoch


My guess is that you probably do not have a definition in your routes file for the action you just defined in the controller. Both an action in the controller and an action in the routes file must be defined for Rails to generate urls correctly.

Your routes file probably has something like this:

resources :posts

But you want to add more than the standard actions generated by the resources keyword, so try something like this:

resources :posts do 
  member do
    post 'incvotes'
  end
end

This tells routes that you have another action in your posts controller called incvotes that accepts HTTP post requests as long as they are pointed at a member route with the correct action (/posts/14 is a member route, while /posts/ is a 'collection' route). So you will have a new route probably like /posts/14/incvotes that you can post a form to and everything should start working properly.

EDIT:

Actually I guess since you are just adding 1 to an attribute on a model, you don't need a POST action (which are normally associated with posting forms as with create and update). To send a post, you might need to change the HTML in the view to include a form and have it post to the correct url. So you can try that, or you can change your routes file to read get 'incvotes' instead of post 'incvotes'. Sorry for the confusion, hope that helps!

like image 42
Brett Bender Avatar answered Nov 03 '22 21:11

Brett Bender


The incvotes_post route only accepts a HTTP POST, and a link always produces a HTTP GET.

Use a form with a button instead (or do a POST using AJAX).

like image 1
Michiel de Mare Avatar answered Nov 03 '22 20:11

Michiel de Mare