ruby-on-railsrubygemsvote-up-buttons

How do you use a Rails 3 gem method to update a database model?


I am using the Thumb_Up gem for ruby on rails. https://github.com/brady8/thumbs_up

I want users to be able to vote on posts. However, I am unable to figure out how I can allow a user to click a button next to each post and add a vote to the database.

I can get this to happen in the rails console through doing the following:

u=User.first

m=Micropost.first

u.vote_for(m)

However, how can I get this to happen when a button is clicked in view. I am assuming I would have to use ajax, but how would I know the url I need to post to to make this action occur?

Any help would be greatly appreciated.

Update:

Thanks so much for the help! I am still having a problem with the code below.

Here is my routes.rb

resources :microposts do
  post :vote, :on => :member
end

View:

<%= link_to('vote for this post!', vote_micropost_path(@micropost), :method => :post) %>

Controller:

def vote
    @micropost = Micropost.find(params[:id])
  current_user.vote_for @micropost

  # This assumes you'll only call it via AJAX.
  # If your ajax call doesn't return "ok", then you know something went wrong
  render :text => 'ok', :layout => false
end

However, I'm still getting this error: No route matches {:controller=>"microposts", :id=>#, :action=>"vote"}

Would anyone know why the routes aren't matching correctly?


Solution

  • I am assuming Rails 3. Rails 2's routes would look a little different.

    First you would need to define a route in your config/routes.rb file. You could do this many ways. If you already have a route for microposts, you could simply add a "vote" action:

        resources :microposts do
          post :vote, :on => :member
        end
    

    (For clarity, the "post" above refers to the HTTP POST method and has nothing to do with your Micropost class.) If you use that route, you would then need to create a "vote" method in your Microposts controller to catch it. Something like

        def vote
          @post = Micropost.find(params[:id])
          current_user.vote_for @post
    
          # This assumes you'll only call it via AJAX.
          # If your ajax call doesn't return "ok", then you know something went wrong
          render :text => 'ok', :layout => false
        end
    

    Then in your view's AJAX POST call (assuming the example route I gave), you would get the url with:

        vote_micropost_path(@micropost)
    

    It would look like /microposts/56/vote