--- /dev/null
+class QuickvoteController < ApplicationController
+ layout 'vb'
+ model :quick_voter
+ model :vote
+ model :election
+
+ def index
+ @election = QuickVote.find_all(["name = ?", params[:votename]])[0]
+
+ @voter = QuickVoter.find_all(["session_id = ? and election_id = ?",
+ session.session_id, @election.id])[0]
+ unless @voter
+ @voter = QuickVoter.new
+ @voter.election = Election.find_all( [ "name = ?", params[:votename] ] )[0]
+ end
+ end
+
+ def create
+ if params[:quickvote]
+ @quickvote = QuickVote.new(params[:quickvote])
+ if @quickvote.reviewed? and @quickvote.save
+ @quickvote = @quickvote.reload
+ render :action => 'success'
+ end
+ end
+ end
+
+ def change
+ voter = QuickVoter.find_all(["session_id = ?", session.session_id])[0]
+ voter.destroy
+ redirect_to quickvote_url( :votename => params[:votename] )
+ end
+
+ def confirm
+ election = QuickVote.find_all(["name = ?", params[:votename]])[0]
+
+ if QuickVoter.find_all(["session_id = ? and election_id = ?",
+ session.session_id, election.id])[0]
+ flash[:notice] = "You have already voted!"
+ redirect_to quickvote_url( :votename => params[:votename] )
+ else
+ @voter = QuickVoter.new()
+ @voter.election = election
+ @voter.session_id = session.session_id
+ @voter.save
+ @voter.reload
+
+ @voter.vote = Vote.new
+ @voter.vote.votestring = params[:vote][:votestring]
+ @voter.vote.confirm!
+ render :action => 'thanks'
+ end
+ end
+
+ def results
+ @election = Election.find_all( ["name = ?", params[:votename]] )[0]
+
+ preference_tally = []
+ plurality_tally = []
+ approval_tally = []
+ @election.voters.each do |voter|
+ plurality_tally << voter.vote.rankings.sort[0].candidate.id
+ approval_tally << voter.vote.rankings.sort[0..1].collect {|ranking| ranking.candidate.id}
+ preference_tally << voter.vote.rankings.sort.collect {|ranking| ranking.candidate.id}
+ end
+
+ @plurality_result = PluralityVote.new(plurality_tally).result
+ @approval_result = ApprovalVote.new(approval_tally).result
+ @condorcet_result = CloneproofSSDVote.new(preference_tally).result
+ @ssd_result = PureCondorcetVote.new(preference_tally).result
+ @borda_result = BordaVote.new(preference_tally).result
+ @runoff_result = InstantRunoffVote.new(preference_tally).result
+
+ @candidates = {}
+ @election.candidates.each {|c| @candidates[c.id] = c}
+ end
+
+end
end
end
- def create_quickvote
- if params[:quickvote]
- @quickvote = QuickVote.new(params[:quickvote])
- if @quickvote.reviewed? and @quickvote.save
- @quickvote = @quickvote.reload
- render :action => 'success_quickvote'
- end
- end
- end
-
end
end
def confirm
- if params[:votename]
- if Voter.find_all( ["session_id = ?", session.session_id ])[0]
- flash[:notice] = "You have already voted!"
- redirect_to quickvote_url( :votename => params[:votename] )
- else
- @voter = QuickVoter.new()
- @voter.election = Election.find_all( [ "name = ?",
- params[:votename] ] )[0]
- @voter.session_id = session.session_id
- @voter.save
- @voter.reload
-
- @voter.vote = Vote.new
- @voter.vote.votestring = params[:vote][:votestring]
- @voter.vote.save
- @voter.vote.confirm!
- render :action => 'thanks'
- end
-
- elsif authenticate
+ if authenticate
@voter.vote.confirm!
render :action => 'thanks'
else
end
end
- def quickvote
- @voter = QuickVoter.new
- @voter.election = Election.find_all( [ "name = ?", params[:votename] ] )[0]
- end
-
private
def authenticate
password = params[:id]
--- /dev/null
+module QuickvoteHelper
+end
class QuickVoter < Voter
validates_presence_of :session_id
- validates_uniqueness_of :session_id
+
+ # validates_uniqueness_of :session_id
+ # instead we shoudl validate that it's unique for a given election_id
end
self.rankings << ranking
end
end
+
+ def destroy
+ self.destroy_rankings
+ super
+ end
def destroy_rankings
rankings.each { |ranking| ranking.destroy }
belongs_to :election
has_one :vote
+ def destroy
+ vote.destroy if vote
+ super
+ end
+
end
<%= @content_for_layout %>
</div>
- <hr />
- <div id="footer">Copyleft 2006 |
+ <div id="footer">
+ <hr />
+ Copyleft 2006 |
<%= link_to "MIT Media Lab", "http://www.media.mit.edu" %> and
<a href="http://mako.cc">Benjamin Mako Hill</a>
</div>
--- /dev/null
+<% %>
+<% if result.winner? and result.winners.length == 1%>
+ <p><em>The winner is:
+ <strong><%= @candidates[result.winner].name %></strong></em></p>
+<% elsif result.winner? and result.winners.length > 1 %>
+ <p><em>There was a tie. The winners are: <strong><%=
+ result.winners.collect {|w| @candidates[w]}.join(", ") %></strong></em></p>
+<% else %>
+ <p><em>There is no winner using this method. </em></strong></p>
+<% end %>
<% end %>
-<%= form_tag :action => 'create_quickvote' %>
+<%= form_tag :action => 'create' %>
<!--[form:election]-->
<p><label for="quickvote_name">Vote Name<br />
--- /dev/null
+<% %>
+<h1>QuickVote: <em><%= @voter.election.name %></em></h1>
+
+<p><strong>Description:</strong></p>
+<blockquote><%= @voter.election.description %></blockquote>
+
+<h2>Vote in Election</h2>
+<% if @voter.session_id %>
+ <p>You have already voted. You can:</p>
+
+ <ul>
+ <li><%= link_to "Change your vote.", quickaction_url( :votename => @voter.election.name, :action => 'change' ) %></li>
+
+ <li><%= link_to "View election results.", quickaction_url( :votename => @voter.election.name, :action => 'results' ) %></li>
+ </ul>
+<% else %>
+ <%= render_partial 'voter/vote' %>
+<% end %>
--- /dev/null
+<% %>
+
+<h1><em><%= @election.name %></em> Results</h1>
+
+<p>Total Votes: <strong><%= @election.voters.length %></strong></p>
+<div class="mainresultbox">
+<h2>Condorcet (w/ Cloneproof SSD) Results</h2>
+<%= render :partial => 'result', :object => @ssd_result %>
+</div>
+
+<div class="resultbox">
+<h2>Plurality Results</h2>
+<%= render :partial => 'result', :object => @plurality_result %>
+</div>
+
+<div class="resultbox">
+<h2>Approval Result</h2>
+<p><font size="-1">(Assuming top two choices are "approved.")</font></p>
+<%= render :partial => 'result', :object => @approval_result %>
+</div>
+
+<div class="resultbox">
+<h2>Simple Condorcet Results</h2>
+<%= render :partial => 'result', :object => @condorcet_result %>
+</div>
+
+<div class="resultbox">
+<h2>Borda Count Results</h2>
+<%= render :partial => 'result', :object => @borda_result %>
+</div>
+
+<div class="resultbox">
+<h2>Instant Runoff (IRV) Results</h2>
+<%= render :partial => 'result', :object => @runoff_result %>
+</div>
+</div>
<% %>
-<p>Vote Created</p>
-
-<p>You have successfully created a QuickVote.</p>
+<h2>Vote Created</h2:>
<p>QuickVotes are open to the public but are not publicly listed on the
HyperChad site. Voters do not need to log in or authenticate to
--- /dev/null
+<% %>
+
+<p>Your vote has been recorded with the following ranked
+preferences:</p>
+
+<ol>
+ <% for rank in @voter.vote.rankings.sort %>
+ <li><%= rank.candidate.name %> </li>
+ <% end %>
+</ol>
+
+<p>Thanks you voting! You can:</p>
+
+<ul>
+ <li><%= link_to "Change your vote.", quickaction_url( :votename => @voter.election.name, :action => 'change' ) %></li>
+
+ <li><%= link_to "View election results.", quickaction_url( :votename => @voter.election.name, :action => 'results' ) %></li>
+</ul>
+
+
+
+
+
<% %>
-<% if @voter.election.quickvote? %>
- <h1>QuickVote: <em><%= @voter.election.name %></em></h1>
- <p><strong>Description:</strong></p>
- <blockquote><%= @voter.election.description %></blockquote>
-<% else %>
- <p><strong>Election:</strong> <%= @voter.election.name %></p>
- <p><strong>Voter:</strong> <%= @voter.email %></p>
- <p><strong>Description:</strong></p>
- <blockquote><%= @voter.election.description %></blockquote>
-<% end %>
-
-<p><strong>Candidates:</strong></p>
+<p><strong>Candidates or choices:</strong></p>
<ol>
<% for candidate in @voter.election.candidates.sort %>
<li><%= candidate.name %></li>
<% end %>
</ol>
-<hr />
-
-<h2>Place Your Vote Here</h2>
-
-<p>Rank each candidate in order of more preferred to least
-preferred. (e.g., 123 or 321 or 213, etc.)</p>
+<p>In the box below, list each choice in order of most preferred to
+least preferred. <em>(For example, 123 or 321 or 213, etc.)</em></p>
<% if @voter.election.quickvote? %>
- <%= form_tag quickconfirm_url( :votename => @voter.election.name ) %>
+ <%= form_tag quickaction_url( :votename => @voter.election.name, :action => 'confirm') %>
<% else %>
<%= form_tag :action => 'review', :id => @voter.password %>
<% end %>
<%= text_field :vote, :votestring -%>
-<%= submit_tag "Submit!" %>
+<%= submit_tag "Vote!" %>
<%= end_form_tag %>
<% %>
+<p><strong>Election:</strong> <%= @voter.election.name %></p>
+<p><strong>Voter:</strong> <%= @voter.email %></p>
+<p><strong>Description:</strong></p>
+<blockquote><%= @voter.election.description %></blockquote>
+
<%= render_partial 'vote' %>
+++ /dev/null
-<% %>
-<%= render_partial 'vote' %>
# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
map.connect '', :controller => "site"
-
+
map.connect 'quickvote/create',
- :controller => 'site',
- :action => 'create_quickvote'
-
- map.quickconfirm 'quickvote/:votename/confirm',
- :controller => 'voter',
- :action => 'confirm'
+ :controller => 'quickvote',
+ :action => 'create'
+
+ map.quickaction 'quickvote/:votename/:action',
+ :controller => 'quickvote',
+ :requirements => { :action => /(change|confirm|results)/ }
map.quickvote 'quickvote/:votename',
- :controller => 'voter',
- :action => 'quickvote'
+ :controller => 'quickvote',
+ :action => 'index'
# Allow downloading Web Service WSDL as a file with an extension
# instead of a file named 'wsdl'
victors[candidate].length == @election.candidates.length - 1
end
- @winners << winners if winners.length == 1
+ @winners = winners if winners.length == 1
end
end
protected
def verify_vote(vote=nil)
- vote.instance_of?( String )
+ vote ? true : false
end
def tally_vote(candidate)
#footer { text-align: center;
font-size: 12px;
- color: #464646; }
+ color: #464646;
+ clear: both;}
#footer a { font-weight: normal; }
.fieldWithErrors input, .fieldWithErrors select {
background-color: #ffdfdf;
}
+
+.mainresultbox {
+ width: 100%;
+ padding: 7px;
+ margin-right: 10px;
+ margin-bottom: 10px;
+ border-style: dotted;
+ border-width: 1px;
+}
+
+.mainresultbox h1 {
+ text-align: center;
+}
+.resultbox {
+ width:47%;
+ float: left;
+ padding: 7px;
+ margin-right: 10px;
+ margin-bottom: 10px;
+ border-style: dotted;
+ border-width: 1px;
+}
+
+
--- /dev/null
+require File.dirname(__FILE__) + '/../test_helper'
+require 'quickvote_controller'
+
+# Re-raise errors caught by the controller.
+class QuickvoteController; def rescue_action(e) raise e end; end
+
+class QuickvoteControllerTest < Test::Unit::TestCase
+ def setup
+ @controller = QuickvoteController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end