1 class Election < ActiveRecord::Base
6 validates_presence_of :name, :description
8 #validate that method is one of the listed election types
10 attr_reader :plurality_result
11 attr_reader :approval_result
12 attr_reader :condorcet_result
13 attr_reader :ssd_result
14 attr_reader :borda_result
18 def initialize(params={})
20 self.enddate = read_attribute( :enddate ) || \
21 Time.now + 30.days - 1.second
26 @other_methods = ELECTION_TYPES.keys.reject {|i| i == election_method}
34 read_attribute( :startdate ) || Time.now
39 self.voters.each do |voter|
46 self.candidates.each do |candidate|
54 if self.candidates.length <= 1
55 reasons << "You must have at least two candidates."
58 if self.voters.length <= 1
59 reasons << "You must have at least two voters."
71 self.class == 'QuickVote'
83 shortdesc = description.split(/\n/)[0]
87 longdesc = description.split(/\n/)[1..-1].join("")
88 longdesc.length > 0 ? longdesc : nil
91 #Calculate results if not in memcache
93 # Assignment is intentional
94 if Cache and c = Cache.get("election_results:#{id}:#{self.votes.length}")
95 @plurality_result = c['plurality']
96 @approval_result = c['approval']
97 @condorcet_result = c['condorcet']
98 @ssd_result = c['ssd']
99 @borda_result = c['borda']
102 # memcache is available, but missed.
103 results = self.results!
104 Cache.set("election_results:#{id}:#{self.votes.length}", results)
111 #Always Calculate Election Results
113 # initalize the tallies to empty arrays
114 preference_tally = Array.new
115 plurality_tally = Array.new
116 approval_tally = Array.new
118 self.voters.each do |voter|
119 # skip if the voter has not voted or has an unconfirmed vote
120 next unless voter.voted?
122 plurality_tally << voter.vote.rankings.sort[0].candidate.id
123 approval_tally << voter.vote.rankings.sort[0..1].collect \
124 { |ranking| ranking.candidate.id }
125 preference_tally << voter.vote.rankings.sort.collect \
126 { |ranking| ranking.candidate.id }
129 @plurality_result = PluralityVote.new(plurality_tally).result
130 @approval_result = ApprovalVote.new(approval_tally).result
131 @condorcet_result = PureCondorcetVote.new(preference_tally).result
132 @ssd_result = CloneproofSSDVote.new(preference_tally).result
133 @borda_result = BordaVote.new(preference_tally).result
135 { 'plurality' => @plurality_result,
136 'approval' => @approval_result,
137 'condorcet' => @condorcet_result,
138 'ssd' => @ssd_result,
139 'borda' => @borda_result }
145 competitors = self.candidates.sort.collect {|candidate| candidate.id}
146 competitors.each do |candidate|
147 names[candidate] = Candidate.find(candidate).name