Vote Fu

Vote Fu is a Ruby on Rails plugin allows an arbitrary number of entites (including Users) to vote on models. It is adapted from act_as_voteable. Differences from acts_as_voteable include:

  1. You can specify the model name that initiates votes.
  2. You can, with a little tuning, have more than one entity type vote on more than one model type.
  3. Adds “acts_as_voter” behavior to the initiator of votes.
  4. Introduces some newer Rails features like named_scope and :polymorphic keywords

Browse the code at GitHub, or install into your application as described below.

Install


Run the following command:

./script/plugin install git://github.com/peteonrails/vote_fu.git

Create a new rails migration using the generator:

./script/generate voteable

Usage


Make your ActiveRecord model act as voteable.

1
2
3
class Model < ActiveRecord::Base
  acts_as_voteable
end

Make your ActiveRecord model(s) that vote act as voter.

1
2
3
4
5
6
7
class User < ActiveRecord::Base
  acts_as_voter
end
 
class Robot < ActiveRecord::Base
  acts_as_voter
end

To cast a vote for a Model you can do the following:

New Shorthand Syntax

VoteFu supports a shorter voting syntax than acts_as_voteable.

1
2
3
4
5
voter.vote_for(voteable)     # Adds a +1 vote
voter.vote_against(voteable) # Adds a -1 vote
voter.vote(voteable, t_or_f) # Adds either +1 or -1 vote 
                                    # true => +1, 
                                    # false => -1

ActsAsVoteable syntax

The old acts_as_voteable syntax is still supported:

1
2
3
4
vote = Vote.new(:vote => true)
m    = Model.find(params[:id])
m.votes    << vote
user.votes << vote

Querying votes

ActiveRecord models that act as voteable can be queried for the positive votes, negative votes, and a total vote count by using the votes_for, votes_against, and votes_count methods respectively. Here is an example:

1
2
3
positiveVoteCount = m.votes_for
negativeVoteCount = m.votes_against
totalVoteCount    = m.votes_count

And because the Vote Fu plugin will add the has_many votes relationship to your model you can always get all the votes by using the votes property:

1
2
allVotes = voteable.votes
allVotes = voter.votes

The mixin also provides these methods:

1
2
3
4
5
voter.voted_for?(voteable)  # True if the voter voted for this object. 
voter.vote_count([true|false|"all"]) # returns the count of +1, -1, or all votes 
 
voteable.voted_by?(voter) # True if the voter voted for this object. 
@voters = voteable.voters_who_voted

Named Scopes

The Vote model has several named scopes you can use to find vote details:

1
2
3
4
  @pete_votes = Vote.for_voter(pete)
  @post_votes = Vote.for_voteable(post)
  @recent_votes = Vote.recent(1.day.ago)
  @descending_votes = Vote.descending

You can chain these together to make interesting queries:

1
2
# Show all of Pete's recent votes for a certain Post, in descending order (newest first)
@pete_recent_votes_on_post = Vote.for_voter(pete).for_voteable(post).recent(7.days.ago).descending

Credits


Juixe – The original ActsAsVoteable plugin inspired this code.

Xelipe – This plugin is heavily influenced by Acts As Commentable.

More


Documentation from the original acts_as_voteable plugin