Added a series of files so that elections can be created and edited and
author<mako@atdot.cc> <>
Thu, 13 Jul 2006 20:23:20 +0000 (16:23 -0400)
committer<mako@atdot.cc> <>
Thu, 13 Jul 2006 20:23:20 +0000 (16:23 -0400)
such. There is still no functionality for running votes yet.

24 files changed:
app/controllers/elections_controller.rb
app/models/candidate.rb
app/models/election.rb
app/models/raw_voter_list.rb [new file with mode: 0644]
app/models/voter.rb [new file with mode: 0644]
app/models/votes.rb [new file with mode: 0644]
app/views/elections/_candidate_list.rhtml [new file with mode: 0644]
app/views/elections/_candidates_form.rhtml
app/views/elections/_overview_form.rhtml
app/views/elections/_voter_list.rhtml [new file with mode: 0644]
app/views/elections/_voters_form.rhtml [new file with mode: 0644]
app/views/elections/edit_candidates.rhtml
app/views/elections/edit_voters.rhtml
app/views/elections/new_voters.rhtml [new file with mode: 0644]
app/views/elections/show.rhtml
db/create.sql
test/fixtures/candidates.yml [new file with mode: 0644]
test/fixtures/raw_voter_lists.yml [new file with mode: 0644]
test/fixtures/voters.yml [new file with mode: 0644]
test/fixtures/votes.yml [new file with mode: 0644]
test/unit/candidate_test.rb [new file with mode: 0644]
test/unit/raw_voter_list_test.rb [new file with mode: 0644]
test/unit/voter_test.rb [new file with mode: 0644]
test/unit/votes_test.rb [new file with mode: 0644]

index 2b1f282bbd8f519eb24da5af71a9fc7dd69beb17..696028e1287baabe6f3431ea12c337bcee0e4238 100644 (file)
@@ -1,4 +1,8 @@
 class ElectionsController < ApplicationController
+  model :raw_voter_list, :voter, :vote, :candidate
+
+
+  # general methods for dealing with elections
   def index
     list
     render :action => 'list'
@@ -8,6 +12,8 @@ class ElectionsController < ApplicationController
     @election_pages, @elections = paginate :elections, :per_page => 10
   end
 
+  # methods for displaying, creating, and manipulating election overview
+  # data
   def show
     @election = Election.find(params[:id])
   end
@@ -15,6 +21,10 @@ class ElectionsController < ApplicationController
   def new
     @election = Election.new
   end
+  
+  def edit
+    @election = Election.find(params[:id])
+  end
 
   def create_election
     @election = Election.new(params[:election])
@@ -26,6 +36,23 @@ class ElectionsController < ApplicationController
     end
   end
 
+  def update
+    @election = Election.find(params[:id])
+    if @election.update_attributes(params[:election])
+      flash[:notice] = 'Election was successfully updated.'
+      redirect_to :action => 'show', :id => @election
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    election = Election.find(params[:id]).destroy
+    redirect_to :action => 'list'
+  end
+
+  # methods fod display, adding, deleting, and manipulating candidate
+  # information for elections
   def new_candidates
     @election = Election.find( params[:id] )
   end
@@ -44,30 +71,60 @@ class ElectionsController < ApplicationController
     candidate.destroy
   end
 
-  def edit
-    @election = Election.find(params[:id])
+  def edit_candidates
+    @election = Election.find( params[:id] )
   end
 
-  def edit_candidates
+  # methods for displaying, adding, deleting, and manipulating voters
+  # for a particular election
+  def new_voters
     @election = Election.find( params[:id] )
+    if params.has_key?[:raw_voter_list]
+      process_incoming_voters( params[:raw_voter_list] )
+    end
+    @raw_voter_list = RawVoterList.new
+
   end
   
   def edit_voters
     @election = Election.find( params[:id] )
+    if params.has_key?( :raw_voter_list )
+      process_incoming_voters( params[:raw_voter_list] )
+    end
+
+    @raw_voter_list = RawVoterList.new
   end
   
-  def update
-    @election = Election.find(params[:id])
-    if @election.update_attributes(params[:election])
-      flash[:notice] = 'Election was successfully updated.'
-      redirect_to :action => 'show', :id => @election
-    else
-      render :action => 'edit'
-    end
+  def delete_voter
+    voter = Voter.find( params[:id] )
+    voter.destroy
   end
+  
+  private
 
-  def destroy
-    election = Election.find(params[:id]).destroy
-    redirect_to :action => 'list'
-  end
+    def process_incoming_voters(raw_voter_list)
+      incoming_voters = RawVoterList.new( raw_voter_list )
+
+      unless incoming_voters.entries.empty?
+        incoming_voters.each do |new_voter|
+
+          if incoming_voters.email == 0
+            new_voter.contacted = 1
+         elsif incoming_voters.email == 1
+           email_voter( new_voter )
+           new_voter.contacted = 1
+         else
+           new_voter.contacted = 0
+         end
+       
+          # the new voter should be in good shape. save add to the election
+         new_voter.save
+          @election.voters << new_voter
+        end
+      end
+      # reset the next time to have a the same default value for emailing
+      @raw_voter_list = RawVoterList.new
+      @raw_voter_list.email = incoming_voters.email
+    end
 end
index 41d743b3a55ed07c0184605cbba600ba2ebc5c84..44a4d63ff4660f6558d8146bf1c6801d3627e3ba 100644 (file)
@@ -1,2 +1,3 @@
 class Candidate < ActiveRecord::Base
+  belongs_to :election
 end
index be828d0e28fac2512df5f004df1b3053ce5fb3c8..29bf1b03e4897ad36f5345b3ec6521e514a8abdf 100644 (file)
@@ -1,7 +1,19 @@
 class Election < ActiveRecord::Base
   has_many :candidates
+  has_many :voters
+  has_many :votes
   validates_presence_of :name, :description
 
+  require 'date'
+
+  def startdate
+    read_attribute( :startdate ) || DateTime.now
+  end
+
+  def enddate
+    read_attribute( :enddate ) || DateTime.now + 14
+  end
+
   def destroy
     self.candidates.each do |candidate|
       candidate.destroy
diff --git a/app/models/raw_voter_list.rb b/app/models/raw_voter_list.rb
new file mode 100644 (file)
index 0000000..2f7cb28
--- /dev/null
@@ -0,0 +1,22 @@
+class RawVoterList
+
+  attr_accessor :email
+  attr_accessor :input_addresses
+
+  include Enumerable
+
+  def initialize(params={})
+    @email = params[:email] || 1
+    @input_addresses = params[:input_addresses] || String.new
+  end
+
+  def email=(email)
+    @email = email
+  end
+  
+  def each
+    @input_addresses.split("\n").each do |address|
+      yield Voter.new( { :email => address } ) 
+    end
+  end
+end
diff --git a/app/models/voter.rb b/app/models/voter.rb
new file mode 100644 (file)
index 0000000..a63ec67
--- /dev/null
@@ -0,0 +1,3 @@
+class Voter < ActiveRecord::Base
+  belongs_to :election
+end
diff --git a/app/models/votes.rb b/app/models/votes.rb
new file mode 100644 (file)
index 0000000..782f514
--- /dev/null
@@ -0,0 +1,2 @@
+class Votes < ActiveRecord::Base
+end
diff --git a/app/views/elections/_candidate_list.rhtml b/app/views/elections/_candidate_list.rhtml
new file mode 100644 (file)
index 0000000..ca8a5cc
--- /dev/null
@@ -0,0 +1,7 @@
+<% %>
+<ul id="candidate_list">
+  <% @election.candidates.each do |candidate| %>
+    <% @candidate = candidate %>
+      <%= render :partial => 'candidate_line' %>
+    <% end %>
+</ul>
index d739dbf62fdac6210092306c0523dcb06751b5a5..814b38f29945295cb04af224505cb8f779410dc3 100644 (file)
@@ -1,13 +1,6 @@
 <p>Please enter candidates for <strong><%= @election.name %></strong>.</p>
 
-  <ul id="candidates_list">
-     <% @election.candidates.each do |candidate| %>
-       <% @candidate = candidate %>
-       <%= render :partial => 'candidate_line' %>
-     <% end %>
-  </ul>
-
-  <%= form_remote_tag(:update => "candidates_list",
+  <%= form_remote_tag(:update => "candidate_list",
                       :url => { :action => :add_candidate, :id => @election.id },
                       :position => "top" ) %>
 
index b3715e1e0f1f45b93bbd219d497f896a92d3bb8a..4a76b81269ca3d4715c0eba797832c31a3c3bca2 100644 (file)
@@ -9,5 +9,12 @@
 
 <p><label for="election_anonymous">Anonymous Vote</label>
 <%= check_box 'election', 'anonymous', {}, 1, 0  %></p>
+
+<p>Election/Voting Start Date<br />
+<%= datetime_select :election, :startdate %></p>
+
+<p>Election/Voting End Date<br />
+<%= datetime_select :election, :enddate %></p>
+
 <!--[eoform:election]-->
 
diff --git a/app/views/elections/_voter_list.rhtml b/app/views/elections/_voter_list.rhtml
new file mode 100644 (file)
index 0000000..c1035d7
--- /dev/null
@@ -0,0 +1,23 @@
+<%
+# basic election information template
+-%>
+
+<% unless @election.voters.empty? %>
+  <p>The following voters are currently registered for this election:</p>
+
+  <ul>
+    <% @election.voters.each do |voter| %>
+    <div id="voter<%= voter.id %>">
+      <li><%= voter.email %>
+          <% if @edit %>
+          <%= link_to_remote "Delete",
+                      :complete => "Element.remove('voter#{voter.id}')",
+                     :url => { :action => :delete_voter, :id => voter.id } %>
+         <% end %>
+      </li>
+    </div>  
+    <% end %>
+  </ul>
+<% end %>
+
+
diff --git a/app/views/elections/_voters_form.rhtml b/app/views/elections/_voters_form.rhtml
new file mode 100644 (file)
index 0000000..620b508
--- /dev/null
@@ -0,0 +1,10 @@
+<p>Please enter a list of new email addresses of potential voters.</p>
+
+<%= text_area :raw_voter_list, :input_addresses %>
+
+<p>Email voters:
+<%= select :raw_voter_list, :email, [ [ 'Never', 0 ],
+                              [ 'Now', 1 ],
+                              [ 'Vote Start', 2 ] ]  %>
+</p>
+<%= submit_tag "Add" %>
index 2809d10345434b832f6adf43a0241594905b5f1d..0c416d5ee071cb757a11c9b3ff73e10869b23333 100644 (file)
@@ -1,5 +1,14 @@
 <% @edit = true %>
 <h1><strong><%= @election.name %>:</strong> Edit Candidates</h1>
 
+<p>The following are valid options or candidates in this election:</p>
+
+<ul>
+<% @election.candidates.each do |candidate| %>
+   <% @candidate = candidate %>
+   <%= render :partial => 'candidate_line' %>
+<% end %>
+</ul>
+
 <%= render :partial => 'candidates_form' %>
 <%= button_to "Done!", :action => 'show', :id => @election %>
index 64ec446d6c2c93d1c2500e2ae4d462cc3b6495c7..36de3eb3f9e6d6168cebbe543a4e19050d405f00 100644 (file)
@@ -1,4 +1,10 @@
 <% @edit = true %>
 <h1><strong><%= @election.name %>:</strong> Edit Voter Rolls</h1>
 
-<%= button_to "Done!", :action => 'show', :id => @election %>
+<%= render :partial => 'voter_list' %>
+
+<%= form_tag :action => 'edit_voters', :id => @election.id %>
+<%= render :partial => 'voters_form' %>
+<%= end_form_tag %>
+
+<%= button_to 'Done!', :action => 'show', :id => @election.id %>
diff --git a/app/views/elections/new_voters.rhtml b/app/views/elections/new_voters.rhtml
new file mode 100644 (file)
index 0000000..b750085
--- /dev/null
@@ -0,0 +1,8 @@
+<% @edit = true %>
+<h1><strong><%= @election.name %>:</strong> Enter List of Voter Email Addresses</h1>
+
+<%= render :partial => 'voter_list' %>
+
+<%= form_tag :action => 'new_voters', :id => @election.id %>
+<%= render :partial => 'voters_form' %>
+<%= end_form_tag %>
index 0ef2fc594f7c7737a62319c1b94f812fc29ea667..954e480e4b9b2ac1c35340d135805483f5beb29e 100644 (file)
@@ -1,3 +1,4 @@
+<% %>
 <h1>Information On <%= @election.name %></h1>
 
 <h2>Overview <%= link_to "edit", :action => 'edit', :id => @election.id %></h2> 
 
 <h2>Candidates <%= link_to "edit", :action => 'edit_candidates', :id => @election.id %></h2> 
 
-
-The following are valid options or candidates in this election:
-
-<ul>
-<% @election.candidates.each do |candidate| %>
-   <% @candidate = candidate %>
-   <%= render :partial => 'candidate_line' %>
-<% end %>
-</ul>
+<%= render :partial => 'candidate_list' %>
 
 <h2>Voters <%= link_to "edit", :action => 'edit_voters', :id => @election.id %></h2>
+
+<%= render :partial => 'voter_list' %>
index e6013cfaf4a62876bc203b606142015bde80d1cf..b7b50bfa70320f61ee9d4b74c79ecd8119abd9f2 100644 (file)
@@ -22,6 +22,8 @@ create table elections (
  name varchar(100) NOT NULL, 
  description TEXT NOT NULL, 
  anonymous tinyint NOT NULL DEFAULT 0, 
+ startdate datetime NOT NULL, 
+ enddate datetime, 
  primary key (id)
 );
 
@@ -43,8 +45,11 @@ create table candidates (
 drop table if exists voters;
 create table voters (
  id int NOT NULL auto_increment,
username varchar(100) NOT NULL, 
email varchar(100) NOT NULL, 
  password varchar(100) NOT NULL, 
+ contacted tinyint NOT NULL DEFAULT 0, 
+ election_id int NOT NULL, 
+ constraint fk_election_voter foreign key (election_id) references election(id),
  primary key (id)
 );
 
diff --git a/test/fixtures/candidates.yml b/test/fixtures/candidates.yml
new file mode 100644 (file)
index 0000000..8794d28
--- /dev/null
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+first:
+  id: 1
+another:
+  id: 2
diff --git a/test/fixtures/raw_voter_lists.yml b/test/fixtures/raw_voter_lists.yml
new file mode 100644 (file)
index 0000000..8794d28
--- /dev/null
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+first:
+  id: 1
+another:
+  id: 2
diff --git a/test/fixtures/voters.yml b/test/fixtures/voters.yml
new file mode 100644 (file)
index 0000000..8794d28
--- /dev/null
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+first:
+  id: 1
+another:
+  id: 2
diff --git a/test/fixtures/votes.yml b/test/fixtures/votes.yml
new file mode 100644 (file)
index 0000000..8794d28
--- /dev/null
@@ -0,0 +1,5 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+first:
+  id: 1
+another:
+  id: 2
diff --git a/test/unit/candidate_test.rb b/test/unit/candidate_test.rb
new file mode 100644 (file)
index 0000000..b640f0c
--- /dev/null
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class CandidateTest < Test::Unit::TestCase
+  fixtures :candidates
+
+  # Replace this with your real tests.
+  def test_truth
+    assert_kind_of Candidate, candidates(:first)
+  end
+end
diff --git a/test/unit/raw_voter_list_test.rb b/test/unit/raw_voter_list_test.rb
new file mode 100644 (file)
index 0000000..3ed0984
--- /dev/null
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class RawVoterListTest < Test::Unit::TestCase
+  fixtures :raw_voter_lists
+
+  # Replace this with your real tests.
+  def test_truth
+    assert_kind_of RawVoterList, raw_voter_lists(:first)
+  end
+end
diff --git a/test/unit/voter_test.rb b/test/unit/voter_test.rb
new file mode 100644 (file)
index 0000000..0b41048
--- /dev/null
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class VoterTest < Test::Unit::TestCase
+  fixtures :voters
+
+  # Replace this with your real tests.
+  def test_truth
+    assert_kind_of Voter, voters(:first)
+  end
+end
diff --git a/test/unit/votes_test.rb b/test/unit/votes_test.rb
new file mode 100644 (file)
index 0000000..1baaa1b
--- /dev/null
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class VotesTest < Test::Unit::TestCase
+  fixtures :votes
+
+  # Replace this with your real tests.
+  def test_truth
+    assert_kind_of Votes, votes(:first)
+  end
+end

Benjamin Mako Hill || Want to submit a patch?