= Voteable Mongo voteable_mongo allows you to make your Mongoid::Document (mongo_mapper support coming soon) objects voteable (up or down) and tabulate votes count and votes point for you. For instance, in a forum, a user can vote up (or down) on a post or a comment. voteable_mongo is built for speed. It uses only one database request per collection to validate data, update data, and get updated data. Initial idea is based on http://cookbook.mongodb.org/patterns/votes Sample app at https://github.com/vinova/simple_qa Benchmarks at https://github.com/vinova/voteable_benchmarks === Sites using voteable_mongo * http://www.amorveneris.com * http://zheye.org (https://github.com/huacnlee/quora) == Installation === Rails 3.0.x To install the gem, add this to your Gemfile gem 'mongoid' gem 'voteable_mongo' After that, remember to run "bundle install" == Usage === Make Post and Comment voteable, User become the voter post.rb class Post include Mongoid::Document include Mongo::Voteable # set points for each vote voteable self, :up => +1, :down => -1 has_many :comments end comment.rb require 'post' class Comment include Mongoid::Document include Mongo::Voteable belongs_to :post voteable self, :up => +1, :down => -3 # each vote on a comment can affect votes count and point of the related post as well voteable Post, :up => +2, :down => -1 end user.rb class User include Mongoid::Document include Mongo::Voter end === Make a vote @user.vote(@post, :up) Is equivalent to @user.vote(:votee => @post, :value => :up) @post.vote(:voter => @user, :value => :up) In case you don't need to init voter and / or votee objects you can @user.vote(:votee_type => 'Post', :votee_id => post_id, :value => :down) @post.vote(:voter_id => user_id, :value => :up) Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up) === Undo a vote @user.unvote(@comment) === If have voter_id, votee_id and vote value you don't need to init voter and votee objects (suitable for API calls) New vote Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up) Re-vote Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up, :revote => true) Un-vote Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up, :unvote => true) In-case you need updated voteable object, add :return_votee => true votee = Post.vote(:voter_id => user_id, :votee_id => post_id, :value => :up, :return_votee => true) === Get vote_value @user.vote_value(@post) @user.vote_value(:class_type => 'Post', :votee_id => post_id) @post.vote_value(@user) @post.vote_value(user_id) === Check if voted? @user.voted?(@post) @user.voted?(:class_type => 'Post', :votee_id => post_id) @post.voted_by?(@user) @post.voted_by?(user_id) === Get votes counts and points puts @post.votes_point puts @post.votes_count puts @post.up_votes_count puts @post.down_votes_count === Get voters given voted object and voter class @post.up_voters(User) @post.down_voters(User) @post.voters(User) - or - User.up_voted_for(@post) User.down_voted_for(@post) User.voted_for(@post) === Get the list of voted objects of a class Post.voted_by(@user) Post.up_voted_by(@user) Post.down_voted_by(@user) == Utilities === Re-generate counters and vote points in case you change :up / :down vote points Rails rake mongo:voteable:remake_stats Ruby Mongo::Voteable::Tasks.remake_stats === Set counters and point to 0 for uninitialized voteable objects in order sort and query Rails rake mongo:voteable:init_stats Ruby Mongo::Voteable::Tasks::init_stats === Migrate from version < 0.7.0 Rails rake mongo:voteable:migrate_old_votes Ruby Mongo::Voteable::Tasks.migrate_old_votes == Credits * Alex Nguyen (alex@vinova.sg) - Author * Stefan Nguyen (stefan@vinova.sg) - Unvoting Copyright (c) 2010-2011 Vinova Pte Ltd (http://vinova.sg) Licensed under the MIT license.