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
# Initialize BallotBox request manager and set its configurations.
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 © 2012 Fodojo, released under the MIT license