11

I am attempting to implement the thumbs_up voting gem on a Rails 3 app, however the instructions are unclear on the actual implementation. After requiring the gem [gem 'thumbs_up'] and after creating and running the appropriate migration [rails generate thumbs_up && rake db:migrate] the README explains the following:

To cast a vote for a Model you can do the following:
*Shorthand syntax
voter.vote_for(voteable) # Adds a +1 vote
voter.vote_against(voteable) # Adds a -1 vote
voter.vote(voteable, vote) # Adds either a +1 or -1 vote: vote => true (+1), vote => false (-1)

voter.vote_exclusively_for(voteable) # Removes any previous votes by that particular voter, and votes for.
voter.vote_exclusively_against(voteable) # Removes any previous votes by that particular voter, and votes against.*

I've been assuming that the use of 'voter' and 'voteable' in the README example are stand-ins for objects in the app, but the usage is still nebulous to me.

A literal example of what my view, controller, and routes.rb file should look like would be a TREMENDOUS help. I've spent days trying to figure this out!

In my app, I have Users that vote on Posts - of which there are two types - Events and Links. Posts are called using <%= render :partial => @posts %> and each individual post uses as its view "_event.html.erb" or "_link.html.erb" - depending whether it is an event or a link.

user000001
  • 32,226
  • 12
  • 81
  • 108
neon
  • 111
  • 1
  • 4

3 Answers3

24

Hopefully I can help you out a bit.

The generators should have created a Vote model for you. This is the model that holds all the votes, but that you interact with indirectly through the methods you've described above.

So, for you:

class User < ActiveRecord::Base
  acts_as_voter
end

class Post < ActiveRecord::Base
  acts_as_voteable
end

That will get you set up with the thumbs_up methods in each of the models.

Then for example, if you have a controller action in PostsController that is linked to from an "up arrow" on your website, you can create a vote for that user for that post.

A view like this:

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

and a routes.rb like this:

resources :posts do
  member do
    post :vote_up
  end
end

And finally, in the controller:

class PostsController < ApplicationController
  def vote_up
    begin
      current_user.vote_for(@post = Post.find(params[:id]))
      render :nothing => true, :status => 200
    rescue ActiveRecord::RecordInvalid
      render :nothing => true, :status => 404
    end
  end
end
bouchard
  • 820
  • 10
  • 27
  • 1
    Hey brady8, can there be more than one model that `acts_as_voter` ? For instance, say I have a `User` model, and a `client` model. Can both of them act as a voter and it works fine ? – marcamillion Feb 19 '11 at 08:36
  • @brady8 I am getting the same NoMethod error as mentioned in the answer below. Could you please elaborate on that? – Dev R Jan 09 '12 at 15:07
  • This just brings me to an empty template at /posts/:id/vote_up – ajbraus Apr 10 '13 at 15:50
  • @ajbraus, yes, that's how it's coded (render nothing). The vote happens, which is what matters... what you do afterward is up to you and application specific. – bouchard Aug 19 '13 at 13:47
1

Routing Error

No route matches {:action=>"vote_up", :controller=>"microposts", :id=>nil}

this is the link I am using and assume this is where the routing isn't being specified correctly. I ran rake routes and there is a route called vote_up_micropost. Is there anything else I should look into. Thank you

here is the link I added

<%= link_to('vote for this post!',
    vote_up_micropost_path(@microposts),
    :method => :post) %>
fthiella
  • 48,073
  • 15
  • 90
  • 106
0

This is just a continuation of Brady's answer.

Brady had the following code in his view

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

what he means is.. since link_to by default uses :method => 'get' & he wanted to update the record using post & not get so he is using :method => 'post'

U can use <%= button_to('vote for this post!', vote_up_post_path(@post) %>, because button by default uses :method => :post

so the routes should be

resources :posts do
  member do
    post :vote_up
  end
end

here in post :vote_up inside the member, its the method => :post & not the post controller

but if you are determined to use link_to without :method => :post something like this

<%= link_to('vote for this post!', vote_up_post_path(@post)) %>

then your routing should be

resources :posts do
   member do
      get :vote_up
   end
end

Hope this helps!

gkolan
  • 1,571
  • 2
  • 20
  • 37