module RedmineCrm module ActsAsVotable module Voter def self.included(base) # allow user to define these aliases = { :vote_up_for => [:likes, :upvotes, :up_votes], :vote_down_for => [:dislikes, :downvotes, :down_votes], :unvote_for => [:unlike, :undislike], :voted_on? => [:voted_for?], :voted_up_on? => [:voted_up_for?, :liked?], :voted_down_on? => [:voted_down_for?, :disliked?], :voted_as_when_voting_on => [:voted_as_when_voted_on, :voted_as_when_voting_for, :voted_as_when_voted_for], :find_up_voted_items => [:find_liked_items], :find_down_voted_items => [:find_disliked_items] } base.class_eval do has_many :votes, :class_name => 'RedmineCrm::ActsAsVotable::Vote', :as => :voter, :dependent => :destroy do def votables includes(:votable).map(&:votable) end end aliases.each do |method, links| links.each do |new_method| alias_method(new_method, method) end end end end # voting def vote(args) args[:votable].vote_by args.merge(:voter => self) end def vote_up_for(model = nil, args = {}) vote :votable => model, :vote_scope => args[:vote_scope], :vote => true end def vote_down_for(model = nil, args = {}) vote :votable => model, :vote_scope => args[:vote_scope], :vote => false end def unvote_for(model, args = {}) model.unvote :voter => self, :vote_scope => args[:vote_scope] end # results def voted_on?(votable, args = {}) votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name, :vote_scope => args[:vote_scope]) !votes.empty? end def voted_up_on?(votable, args = {}) votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name, :vote_scope => args[:vote_scope], :vote_flag => true) !votes.empty? end def voted_down_on?(votable, args = {}) votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name, :vote_scope => args[:vote_scope], :vote_flag => false) !votes.empty? end def voted_as_when_voting_on(votable, args = {}) vote = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name, :vote_scope => args[:vote_scope]).select(:vote_flag).last return nil unless vote vote.vote_flag end def find_votes(extra_conditions = {}) votes.where(extra_conditions) end def find_up_votes(args = {}) find_votes :vote_flag => true, :vote_scope => args[:vote_scope] end def find_down_votes(args = {}) find_votes :vote_flag => false, :vote_scope => args[:vote_scope] end def find_votes_for_class(klass, extra_conditions = {}) find_votes extra_conditions.merge(:votable_type => klass.name) end def find_up_votes_for_class(klass, args = {}) find_votes_for_class klass, :vote_flag => true, :vote_scope => args[:vote_scope] end def find_down_votes_for_class(klass, args = {}) find_votes_for_class klass, :vote_flag => false, :vote_scope => args[:vote_scope] end # Including polymporphic relations for eager loading def include_objects RedmineCrm::ActsAsVotable::Vote.includes(:votable) end def find_voted_items(extra_conditions = {}) options = extra_conditions.merge :voter_id => id, :voter_type => self.class.base_class.name include_objects.where(options).collect(&:votable) end def find_up_voted_items(extra_conditions = {}) find_voted_items extra_conditions.merge(:vote_flag => true) end def find_down_voted_items(extra_conditions = {}) find_voted_items extra_conditions.merge(:vote_flag => false) end def get_voted(klass, extra_conditions = {}) klass.joins(:votes_for).merge find_votes(extra_conditions) end def get_up_voted(klass) klass.joins(:votes_for).merge find_up_votes end def get_down_voted(klass) klass.joins(:votes_for).merge find_down_votes end end end end