Election results in the London Borough of Sutton.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

models.rb 5.9 KiB

13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. require 'data_mapper'
  2. load '_config.rb'
  3. class Poll
  4. include DataMapper::Resource
  5. property :district_id, Integer, :key => true
  6. property :election_id, Integer, :key => true
  7. property :electorate, Integer # The number of people eligible to vote in this district in this election
  8. property :ballot_papers_issued, Integer # The number of ballot papers issued (includes spoiled ballots)
  9. property :seats, Integer, :required => true # The number of seats to be elected in this district in this election
  10. property :rejected_no_official_mark, Integer
  11. property :rejected_too_many_candidates, Integer
  12. property :rejected_identifiable_voter, Integer
  13. property :rejected_blank_or_uncertain, Integer
  14. def turnout_percent
  15. @ballot_papers_issued.to_f / @electorate.to_f * 100.0
  16. end
  17. def total_rejected_ballots
  18. if @rejected_no_official_mark
  19. @rejected_no_official_mark + \
  20. @rejected_too_many_candidates + \
  21. @rejected_identifiable_voter + \
  22. @rejected_blank_or_uncertain
  23. else
  24. nil
  25. end
  26. end
  27. def valid_ballot_papers
  28. self.total_rejected_ballots ? @ballot_papers_issued - self.total_rejected_ballots : nil
  29. end
  30. def successful_candidacies # Candidacies where the candidate was elected
  31. Candidacy.all(:election => @election, :district => @district, :order => [:position], :limit => @seats)
  32. end
  33. # Set candidacy.position for every candidacy in this poll
  34. # Returns array of candidacies, or false if we don't have results for this poll
  35. def set_positions
  36. # Check that every candidacy for this poll has its votes recorded (ie that the election results are known)
  37. return false if Candidacy.count(:conditions => { :district_id => @district_id, :election_id => @election_id, :votes => nil }) > 0
  38. # Get the candidacies for this poll
  39. ccys = Candidacy.all(:conditions => { :district_id => @district_id, :election_id => @election_id }, :order => [:votes.desc])
  40. puts "Found no candidacies for this poll" if ccys.size == 0
  41. position = 1
  42. ccys.each do |ccy|
  43. position <= @seats ? ccy.seats = 1 : ccy.seats = 0
  44. ccy.position = position
  45. ccy.save
  46. position += 1
  47. end
  48. ccys
  49. end
  50. belongs_to :election
  51. belongs_to :district
  52. end
  53. class Candidate
  54. include DataMapper::Resource
  55. property :id, Serial
  56. property :forenames, String, :required => true
  57. property :surname, String, :required => true, :index => true
  58. has n, :candidacies#, 'Candidacy'
  59. def short_name
  60. @forenames.split(' ')[0] + ' ' + @surname
  61. end
  62. def name
  63. @forenames + ' ' + @surname
  64. end
  65. def url
  66. "/candidates/" + @id.to_s
  67. end
  68. end
  69. class DeletedCandidate
  70. include DataMapper::Resource
  71. property :old_candidate_id, Integer, :key => true # ID of candidate that has been merged/deleted
  72. property :candidate_id, Integer, :required => true # ID of candidate that has been kept
  73. end
  74. class Candidacy
  75. include DataMapper::Resource
  76. property :id, Serial
  77. property :election_id, Integer, :required => true
  78. property :candidate_id, Integer, :required => true
  79. property :party_id, Integer
  80. property :district_id, Integer, :required => true
  81. property :votes, Integer
  82. property :address, String, :length => 200
  83. property :postcode, String
  84. property :position, Integer # Position of this candidate in this district. (1..n)
  85. property :seats, Integer # Number of seats won by this candidacy (0 or 1)
  86. property :labcoop, String, :default => '0' # Candidacy is for joint Labour/Co-op party
  87. belongs_to :election
  88. belongs_to :candidate
  89. belongs_to :party
  90. belongs_to :district
  91. end
  92. class Election
  93. include DataMapper::Resource
  94. property :id, Serial
  95. property :body_id, Integer, :required => true
  96. property :d, Date, :required => true, :index => true
  97. property :reason, String, :length => 255
  98. property :kind, String, :length => 255
  99. has n, :candidacies
  100. has n, :polls
  101. belongs_to :body
  102. def self.past
  103. self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
  104. end
  105. def self.future
  106. self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
  107. end
  108. # electorate and ballot_papers_issued assume there's a Poll object for every district in this election
  109. def electorate
  110. Poll.sum(:electorate, :election => self)
  111. end
  112. def ballot_papers_issued
  113. Poll.sum(:ballot_papers_issued, :election => self)
  114. end
  115. def set_positions
  116. polls.each { |p| p.set_positions }
  117. end
  118. end
  119. class District
  120. include DataMapper::Resource
  121. property :id, Serial
  122. property :body_id, Integer, :required => true
  123. property :name, String, :length => 255, :required => true
  124. property :slug, String
  125. property :ons_district_code, String
  126. belongs_to :body
  127. has n, :polls
  128. def self.slugify(name)
  129. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  130. end
  131. end
  132. class Body
  133. include DataMapper::Resource
  134. property :id, Serial
  135. property :name, String, :length => 255, :required => true
  136. property :district_name, String, :length => 255, :required => true # singular
  137. property :districts_name, String, :length => 255, :required => true # plural
  138. property :slug, String, :length => 255
  139. has n, :elections
  140. has n, :districts
  141. end
  142. class Party
  143. include DataMapper::Resource
  144. property :id, Serial
  145. property :name, String, :required => true
  146. property :colour, String
  147. has n, :candidacies
  148. # has n, :campaigns
  149. end
  150. DataMapper.setup(:default, ENV['DATABASE_URL'])
  151. DataMapper.repository(:default).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::UnderscoredAndPluralized
  152. DataMapper.auto_upgrade!