* refactored the system so that it keeps pictures in a seperate table
author<mako@atdot.cc> <>
Fri, 24 Aug 2007 23:36:06 +0000 (19:36 -0400)
committer<mako@atdot.cc> <>
Fri, 24 Aug 2007 23:36:06 +0000 (19:36 -0400)
  but works almost almost identically

* added a new progress bar

* fixed a few minor bugs and walked through creating a full-fledged
  election

13 files changed:
app/controllers/election_controller.rb
app/models/candidate.rb
app/models/election.rb
app/models/picture.rb [new file with mode: 0644]
app/views/election/_progress.rhtml [new file with mode: 0644]
app/views/election/edit_candidates.rhtml
app/views/election/general_information.rhtml [moved from app/views/election/new.rhtml with 80% similarity]
app/views/election/new_voters.rhtml
app/views/election/show.rhtml
app/views/site/_basic_login.rhtml
db/create.sql
db/schema.rb
public/stylesheets/main.css

index d3332948b4398a197ca8280d69ec8db351ea7be2..7040c38c26b7acdb8ee2bc50bacb5a42c16e6909 100644 (file)
@@ -12,7 +12,12 @@ class ElectionController < ApplicationController
   ####################################################################
 
   def new
+    redirect_to :action => 'general_information'
+  end
+  
+  def general_information
     @election = Election.new
+    render :action => 'general_information'
   end
   
   def create_election
@@ -27,7 +32,7 @@ class ElectionController < ApplicationController
       flash[:notice] = 'Election was successfully created.'
       redirect_to :action => 'edit_candidates', :id => @election.id
     else
-      render :action => 'new'
+      render :action => 'general_information'
     end
   end
   
@@ -73,9 +78,9 @@ class ElectionController < ApplicationController
   def add_candidate
     @election = Election.find(params[:id])
     @candidate = Candidate.new(params[:candidate])
-    
+    @election.candidates << @candidate
+
     if @candidate.save
-      @election.candidates << @candidate
       @candidate = Candidate.new
       redirect_to :action => 'edit_candidates', :id => @election.id
     else
@@ -118,9 +123,9 @@ class ElectionController < ApplicationController
 
   def candidate_picture
     candidate = Candidate.find( params[:id] )
-    send_data( candidate.picture_data,
-               :filename => candidate.picture_filename,
-              :type => candidate.picture_type,
+    send_data( candidate.picture.data,
+               :filename => candidate.picture.filename,
+              :type => candidate.picture.filetype,
               :disposition => 'inline' )
   end
 
@@ -128,12 +133,7 @@ class ElectionController < ApplicationController
   ## 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
-
+    edit_voters
   end
   
   def edit_voters
@@ -207,8 +207,8 @@ class ElectionController < ApplicationController
           end
        
           # the new voter should be in good shape. save add to the election
-               new_voter.save
           @election.voters << new_voter
+               new_voter.save
         end
       end
  
index 430b6ab22762223a728eaf6cc27bb3d51f7b8d2e..eeba4d228032499b8d15474123b03e9aa8129208 100644 (file)
@@ -2,6 +2,10 @@ class Candidate < ActiveRecord::Base
   belongs_to :election
   validates_presence_of :name
 
+  # i have to call this picture_assoc because picture= does not overload
+  # the normal association method made by has_one
+  has_one :picture_obj, :class_name => "Picture"
+
   # validate uniqueness of a name *within a given election*
 
   def <=>(other)
@@ -12,24 +16,21 @@ class Candidate < ActiveRecord::Base
     name
   end
 
-  def picture=(picture_field)
-    if picture_field
-      unless picture_field.content_type.match(/^image/)
-        return false
-      end
-      self.picture_filename = base_part_of(picture_field.original_filename)
-      self.picture_type =  picture_field.content_type.chomp
-      self.picture_data = picture_field.read
-    end
+  def picture
+    picture_obj
   end
 
-  def base_part_of(filename)
-    name = File.basename(filename)
-    name.gsub(/[^\w._-]/, '')
+  def picture=(field)
+    if field and field.length > 0
+      self.picture_obj = Picture.new.set_from_field(field)
+      return picture_obj.save
+    else
+      return false
+    end
   end
 
   def picture?
-    !self.picture_filename.nil?
+    !self.picture_obj.nil?
   end
 
 end
index a574139c535abc4f48b7ba5a210da7d918e5362d..a77f4457bb581fba8588e1cf7ee479932851f409 100644 (file)
@@ -57,7 +57,6 @@ class Election < ActiveRecord::Base
 
   def start_blockers
     reasons = []
-    debugger 
     if self.candidates.length <= 1
       reasons << "You must have at least two candidates."
     end
diff --git a/app/models/picture.rb b/app/models/picture.rb
new file mode 100644 (file)
index 0000000..e7df084
--- /dev/null
@@ -0,0 +1,20 @@
+class Picture < ActiveRecord::Base
+  belongs_to :candidate
+  def set_from_field(field)
+    unless field.content_type.match(/^image/)
+      return false
+    end
+    self.filename = base_part_of(field.original_filename)
+    self.filetype =  field.content_type.chomp
+    self.data = field.read
+    self
+  end
+
+  def base_part_of(filename)
+    name = File.basename(filename)
+    name.gsub(/[^\w._-]/, '')
+  end
+
+end
+
diff --git a/app/views/election/_progress.rhtml b/app/views/election/_progress.rhtml
new file mode 100644 (file)
index 0000000..520894c
--- /dev/null
@@ -0,0 +1,16 @@
+<% progress_steps = [ ['overview', 'General Information'],
+                      ['candidates', 'Candidates'],
+                      ['voters', 'Voters'],
+                      ['review', 'Review'] ] %>
+<div id="election_creation_progress_bar">
+
+<ul>
+<% progress_steps.each_with_index do |kv, i| -%>
+  <% step, description = kv -%>
+  <li class="<%= step == progress ? 'step_selected' : 'step_unselected' -%>
+             <%= " last" if i + 1 == progress_steps.length -%>
+             ">Step <%= i + 1 %>: <%= description %></li>
+<% end -%>
+</ul>
+
+</div>
index 99f2f129abd0607b2308d256d52572dc775d6c96..837f75560760d0ea03d0b6a652eaf25106682bbc 100644 (file)
@@ -1,9 +1,11 @@
+<%= render_partial 'progress', 'candidates' %>
 <h1>Edit/Add Candidates</h1>
 
 <%= error_messages_for :candidate %>
 
 <% unless @election.candidates.empty? %>
   <p>The following are valid options or candidates in this election:</p>
+1;3A
 
   <% @election.candidates.each do |candidate| %>
     <% @current_candidate = candidate %>
@@ -22,4 +24,4 @@
 <%= submit_tag "Add Candidate" %>
 <% end %>
 
-<%= button_to "Done!", :action => 'show', :id => @election %>
+<%= button_to "Done!", :action => 'new_voters', :id => @election %>
similarity index 80%
rename from app/views/election/new.rhtml
rename to app/views/election/general_information.rhtml
index 7b717486c0042739b2fe91d53b0f492e52677901..0a1a51394c5dff7dc1a8fabdec0cf45bc50e30ca 100644 (file)
@@ -1,3 +1,5 @@
+<%= render_partial 'progress', 'overview' %>
+
 <h1>Create A New Vote</h1>
 
 <h2>Vote Overview</h2>
index 9c3bad3a6f9c99cb36b07a35f19806ef8503ed7f..fc49e13638167dd8fa026ac7e373625e1885ee82 100644 (file)
@@ -1,3 +1,4 @@
+<%= render_partial 'progress', 'voters' %>
 <% @edit = true %>
 <h1><strong><%= @election.name %>:</strong> Enter List of Voter Email Addresses</h1>
 
@@ -6,3 +7,4 @@
 <% form_tag(:action => 'new_voters', :id => @election.id) do %>
 <%= render :partial => 'voters_form' %>
 <% end %>
+<%= button_to "Done", :action => 'show', :id => @election.id %>
index 0051861e3475c418d9480a08cf7f0cc5208f9461..ff06521da1dbb997e55b118babd2aeade7985748 100644 (file)
@@ -1,4 +1,4 @@
-<% %>
+<%= render_partial 'progress', 'review' %>
 <h1>Vote Information</h1>
 
 <% if @election.active? %>
@@ -54,7 +54,7 @@
   <p><em>There are currently no voters registered.  <%= link_to "Add some!", :action => 'edit_voters', :id => @election.id unless @election.active %></em></p>
 <% end %>
 
-<% unless @election.active %>
+<% unless @election.active? %>
   <h2>Start Election</h2>
 
   <% if @election.start_blockers.length > 0 %>
index f02d362819f23e478b82705f434d99ab89ea0ded..689a3f56a231ac88e526cdaf52991dfa2cd2eecf 100644 (file)
 
       <p><%= link_to 'Lost or forgot your password?', :controller => 'account', :action => 'forgot_password' %></p>
 
-      <p>Unfortunately, Selectricity is currently being tested and new
-      accounts for full votes (i.e., non-<em>QuickVotes</em>) can not
-      be automatically created. If you are interested in using
-      Selectricity to
-      run an organizational election, contact <a
-      href="http://mako.cc/contact.html">Benjamin Mako Hill</a>.</p>
-
     </div>
 
index a5a2e0a0fb54b1458ae5e1abb8a8394fb0b454d1..298b99a63276515661ad7839f782d3a995699539 100644 (file)
@@ -27,9 +27,20 @@ create table candidates (
  election_id int NOT NULL,
  name varchar(100) NOT NULL, 
  description text NULL,
- picture_filename varchar(200),
- picture_data blob, 
- picture_type varchar(100), 
+ primary key (id)
+);
+
+# CREATE pictures TABLE
+#####################################
+
+drop table if exists pictures;
+create table pictures (
+ id int NOT NULL auto_increment,
+ filename varchar(200),
+ data blob, 
+ filetype varchar(100), 
+ candidate_id int NULL,
+ constraint fk_candidate_picture foreign key (candidate_id) references candidates(id),
  primary key (id)
 );
 
index 761fe47a5a21ec21d0f699b73010416a5be5a62c..57e39ac71a9e5a32490b72134fe9992cb5668dc1 100644 (file)
@@ -5,12 +5,9 @@
 ActiveRecord::Schema.define() do
 
   create_table "candidates", :force => true do |t|
-    t.column "election_id",      :integer,                                :null => false
-    t.column "name",             :string,  :limit => 100, :default => "", :null => false
-    t.column "description",      :text
-    t.column "picture_filename", :string,  :limit => 200
-    t.column "picture_data",     :binary
-    t.column "picture_type",     :string,  :limit => 100
+    t.column "election_id", :integer,                                :null => false
+    t.column "name",        :string,  :limit => 100, :default => "", :null => false
+    t.column "description", :text
   end
 
   create_table "elections", :force => true do |t|
@@ -28,6 +25,15 @@ ActiveRecord::Schema.define() do
 
   add_index "elections", ["user_id"], :name => "fk_user_election"
 
+  create_table "pictures", :force => true do |t|
+    t.column "filename",     :string,  :limit => 200
+    t.column "data",         :binary
+    t.column "filetype",     :string,  :limit => 100
+    t.column "candidate_id", :integer
+  end
+
+  add_index "pictures", ["candidate_id"], :name => "fk_candidate_picture"
+
   create_table "rankings", :force => true do |t|
     t.column "vote_id",      :integer
     t.column "candidate_id", :integer
index 5072139da2df3066848d748920a125c7d604f89c..76eff61026e1a05c6a188d0a779280c77ea8c196 100644 (file)
@@ -313,3 +313,26 @@ li.moveable {
   padding: 5px;
 }
 
+#election_creation_progress_bar ul li {
+  display: inline;
+  list-style: default;
+}
+
+#election_creation_progress_bar ul li:after {
+  font-weight: normal;
+  color: #000;
+  content: " || ";
+}
+
+#election_creation_progress_bar ul li.last:after {
+  content: "";
+}
+
+#election_creation_progress_bar li.step_selected {
+  font-weight: bold;
+}
+
+#election_creation_progress_bar li.step_unselected {
+  color: #CCCCCC;
+  font-weight: bold;
+}

Benjamin Mako Hill || Want to submit a patch?