|
- require 'data_mapper'
-
- class Poll
- include DataMapper::Resource
-
- property :district_id, Integer, :key => true
- property :election_id, Integer, :key => true
- property :electorate, Integer # The number of people eligible to vote in this district in this election
- property :ballot_papers_issued, Integer # The number of ballot papers issued (includes spoiled ballots)
- property :seats, Integer, :required => true # The number of seats to be elected in this district in this election
- property :rejected_no_official_mark, Integer
- property :rejected_too_many_candidates, Integer
- property :rejected_identifiable_voter, Integer
- property :rejected_blank_or_uncertain, Integer
-
- def turnout_percent
- @ballot_papers_issued.to_f / @electorate.to_f * 100.0
- end
-
- def total_rejected_ballots
- if @rejected_no_official_mark
- @rejected_no_official_mark + \
- @rejected_too_many_candidates + \
- @rejected_identifiable_voter + \
- @rejected_blank_or_uncertain
- else
- nil
- end
- end
-
- def valid_ballot_papers
- self.total_rejected_ballots ? @ballot_papers_issued - self.total_rejected_ballots : nil
- end
-
- def successful_candidacies # Candidacies where the candidate was elected
- Candidacy.all(:election => @election, :district => @district, :order => [:position], :limit => @seats)
- end
-
- # Set candidacy.position for every candidacy in this poll
- # Returns array of candidacies, or false if we don't have results for this poll
- def set_positions
- # Check that every candidacy for this poll has its votes recorded (ie that the election results are known)
- return false if Candidacy.count(:conditions => { :district_id => @district_id, :election_id => @election_id, :votes => nil }) > 0
-
- # Get the candidacies for this poll
- ccys = Candidacy.all(:conditions => { :district_id => @district_id, :election_id => @election_id }, :order => [:votes.desc])
-
- puts "Found no candidacies for this poll" if ccys.size == 0
-
- position = 1
- ccys.each do |ccy|
- position <= @seats ? ccy.seats = 1 : ccy.seats = 0
- ccy.position = position
- ccy.save
- position += 1
- end
- ccys
- end
-
- belongs_to :election
- belongs_to :district
- end
-
- class Candidate
- include DataMapper::Resource
-
- property :id, Serial
- property :forenames, String, :required => true
- property :surname, String, :required => true, :index => true
-
- has n, :candidacies#, 'Candidacy'
-
- def short_name
- @forenames.split(' ')[0] + ' ' + @surname
- end
-
- def name
- @forenames + ' ' + @surname
- end
-
- def url
- "/candidates/" + @id.to_s
- end
- end
-
- class DeletedCandidate
- include DataMapper::Resource
-
- property :old_candidate_id, Integer, :key => true # ID of candidate that has been merged/deleted
- property :candidate_id, Integer, :required => true # ID of candidate that has been kept
- end
-
- class Candidacy
- include DataMapper::Resource
-
- property :id, Serial
- property :election_id, Integer, :required => true
- property :candidate_id, Integer, :required => true
- property :party_id, Integer
- property :district_id, Integer, :required => true
- property :votes, Integer
- property :address, String, :length => 200
- property :postcode, String
- property :position, Integer # Position of this candidate in this district. (1..n)
- property :seats, Integer # Number of seats won by this candidacy (0 or 1)
- property :labcoop, String, :default => '0' # Candidacy is for joint Labour/Co-op party
-
- belongs_to :election
- belongs_to :candidate
- belongs_to :party
- belongs_to :district
- end
-
- class Election
- include DataMapper::Resource
-
- property :id, Serial
- property :body_id, Integer, :required => true
- property :d, Date, :required => true, :index => true
- property :reason, String, :length => 255
- property :kind, String, :length => 255
-
- has n, :candidacies
- has n, :polls
- belongs_to :body
-
- def self.past
- self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
- end
-
- def self.future
- self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
- end
-
- # electorate and ballot_papers_issued assume there's a Poll object for every district in this election
- def electorate
- Poll.sum(:electorate, :election => self)
- end
-
- def ballot_papers_issued
- Poll.sum(:ballot_papers_issued, :election => self)
- end
-
- def set_positions
- polls.each { |p| p.set_positions }
- end
- end
-
- class District
- include DataMapper::Resource
-
- property :id, Serial
- property :body_id, Integer, :required => true
- property :name, String, :length => 255, :required => true
- property :slug, String
- property :ons_district_code, String
-
- belongs_to :body
- has n, :polls
-
- def self.slugify(name)
- name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
- end
- end
-
- class Body
- include DataMapper::Resource
-
- property :id, Serial
- property :name, String, :length => 255, :required => true
- property :district_name, String, :length => 255, :required => true # singular
- property :districts_name, String, :length => 255, :required => true # plural
- property :slug, String, :length => 255
-
- has n, :elections
- has n, :districts
- end
-
- class Party
- include DataMapper::Resource
-
- property :id, Serial
- property :name, String, :required => true
- property :colour, String
-
- has n, :candidacies
- # has n, :campaigns
- end
-
- DataMapper.setup(:default, ENV['DATABASE_URL'])
- DataMapper.repository(:default).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::UnderscoredAndPluralized
- DataMapper.auto_upgrade!
|