= BallotBox
The BallotBox gem enables visitors to vote for and against voteable objects
== Install
gem 'ballot_box'
Create votes table by migration:
rake ballot_box_engine:install:migrations
Or via generator:
rails generate ballot_box:install
== Usage
Use middleware with options: route and voteable_type
config.app_middleware.use BallotBox::Manager do |config| config.routes = { "/posts/votes" => "Post" } end
Set voteable model:
class Post < ActiveRecord::Base ballot_box :counter_cache => true, :strategies => [:authenticated], :place => :position, :scope => :group_id end
Set votes sum column:
ballot_box :counter_cache => :rating, :strategies => [:authenticated]
Set place (position) column:
ballot_box :place => true, :counter_cache => true
or update place scope conditions:
ballot_box :counter_cache => :rating, :place => "place"
def self.ballot_box_place_scope unscoped.order("rating DESC").where(:is_visible => true) end
Update votes sum directly:
Post.ballot_box_update_votes!
or update votes sum only for one record:
@post.ballot_box_update_votes!
Update place directly for all scopes:
Post.ballot_box_update_place!
or update place only for one scope:
@post.ballot_box_update_place!
View (just send post request to configure route):
link_to 'Vote', "/posts/votes?id=#{@post.id}", :remote => true, :method => :post
== Strategies
Strategy - is no more a simple validation at the object vote. Authenticated - check :voter attribute is not blank.
module BallotBox module Strategies class Authenticated < Base validates_presence_of :voter end end end
Write your own strategies:
class MyCustomStrategy < BallotBox::Strategies::Base validate :check_visible, :check_unique_voter
protected
def check_visible
errors.add(:voteable, :invalid) unless voteable.visible?
end
def check_unique_voter
if vote.class.where(["voter_id = ? AND voter_type = ?", vote.voter_id, vote.voter_type]).exists?
errors.add(:voter, :taken)
end
end
end
class Post < ActiveRecord::Base ballot_box :strategies => [:authenticated, 'MyCustomStrategy'] end
== Callbacks
Middleware callbacks:
BallotBox::Manager.before_vote do |env, vote| vote.voter = env['warden'].user #vote.errors.add(:voter, :empty) end
BallotBox::Manager.after_vote do |env, vote| Rails.logger.info(vote.to_xml) end
ActiveRecord callbacks:
class Post < ActiveRecord::Base ballot_box :counter_cache => true
before_vote :method_before
after_vote :method_after
def method_before
Rails.logger.info current_vote.to_xml
# To terminate register vote, just return false
# return false
end
def method_after
end
end
Copyright (c) 2012 Fodojo, released under the MIT license