Big commit includes:
[selectricity-live] / app / models / election.rb
1 class Election < ActiveRecord::Base
2   has_many :candidates
3   has_many :voters
4   has_many :votes
5   belongs_to :user
6   validates_presence_of :name, :description
7   
8   #validate that method is one of the listed election types
9   
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
15   
16   require 'date'
17   
18   def initialize(params={})
19     super
20     self.enddate = read_attribute( :enddate ) || \
21                    Time.now + 14.days - 1.second
22   end
23
24   def other_methods
25     if election_method
26       @other_methods = ELECTION_TYPES.reject {|i| i == election_method}
27     else
28       @other_methods = nil
29     end
30     @other_methods
31   end
32
33   def startdate
34     read_attribute( :startdate ) || Time.now
35   end
36
37   def enddate=(date)
38     date += 1.day
39     date = Time.gm(*date)
40     super(date)
41   end
42
43   def votes
44     votes = Array.new
45     self.voters.each do |voter|
46       votes << voter.vote
47     end
48     return votes
49   end
50
51   def destroy
52     self.candidates.each do |candidate|
53       candidate.destroy
54     end
55     super
56   end
57
58   def start_blockers
59     reasons = []
60     debugger 
61     if self.candidates.length <= 1
62       reasons << "You must have at least two candidates."
63     end
64     
65     if self.voters.length <= 1
66       reasons << "You must have at least two voters."
67     end
68
69     reasons
70   end
71
72   def activate!
73     self.active = 1
74     self.save!
75   end
76   
77   def quickvote?
78     self.class == 'QuickVote'
79   end
80
81   def active?
82     active == 1
83   end 
84
85   def done?
86     active == 2
87   end
88
89   def shortdesc
90     shortdesc = description.split(/\n/)[0]
91   end
92
93   def longdesc
94     longdesc = description.split(/\n/)[1..-1].join("")
95     longdesc.length > 0 ? longdesc : nil 
96   end
97   
98   #Calculate Election Results
99   def results
100     # initalize the tallies to empty arrays
101     preference_tally = Array.new
102     plurality_tally = Array.new
103     approval_tally = Array.new
104
105     self.voters.each do |voter|
106       # skip if the voter has not voted or has an unconfirmed vote
107       next unless voter.voted?
108
109       plurality_tally << voter.vote.rankings.sort[0].candidate.id
110       approval_tally << voter.vote.rankings.sort[0..1].collect \
111         { |ranking| ranking.candidate.id }
112       preference_tally << voter.vote.rankings.sort.collect \
113         { |ranking| ranking.candidate.id }
114     end
115     
116     @plurality_result = PluralityVote.new(plurality_tally).result
117     @approval_result = ApprovalVote.new(approval_tally).result
118     @condorcet_result = PureCondorcetVote.new(preference_tally).result
119     @ssd_result = CloneproofSSDVote.new(preference_tally).result
120     @borda_result = BordaVote.new(preference_tally).result
121     
122     { 'plurality' => @plurality_result,
123       'approval' => @approval_result,
124       'condorcet' => @condorcet_result,
125       'ssd' => @ssd_result,
126       'borda' => @borda_result }
127     end
128   
129   def names_by_id
130     names = Hash.new
131     
132     competitors = self.candidates.sort.collect {|candidate| candidate.id}
133     competitors.each do |candidate|
134       names[candidate] = Candidate.find(candidate).name
135     end
136     
137     names
138   end
139   
140 end
141
142

Benjamin Mako Hill || Want to submit a patch?