# frozen_string_literal: true 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: "ActsAsVotable::Vote", as: :voter, dependent: :delete_all 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.exists? 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.exists? 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.exists? 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 return 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 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