Skip to content
This repository

Add up / down voteability to Mongoid and MongoMapper documents. Optimized for speed by using only ONE request to validate, update, and retrieve updated data.

Fetching latest commit…

Cannot retrieve the latest commit at this time

README.rdoc

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 cookbook.mongodb.org/patterns/votes

Sample app at github.com/vinova/simple_qa

Benchmarks at github.com/vinova/voteable_benchmarks

Sites using voteable_mongo

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 © 2010-2011 Vinova Pte Ltd (vinova.sg)

Licensed under the MIT license.

Something went wrong with that request. Please try again.