Election results in the London Borough of Sutton.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

250 lignes
8.0 KiB

  1. require 'data_mapper'
  2. class Poll
  3. include DataMapper::Resource
  4. property :district_id, Integer, :key => true
  5. property :election_id, Integer, :key => true
  6. property :electorate, Integer # The number of people eligible to vote in this district in this election
  7. property :ballot_papers_issued, Integer # The number of ballot papers issued (includes spoiled ballots)
  8. property :seats, Integer, :required => true # The number of seats to be elected in this district in this election
  9. property :rejected_no_official_mark, Integer
  10. property :rejected_too_many_candidates, Integer
  11. property :rejected_identifiable_voter, Integer
  12. property :rejected_blank_or_uncertain, Integer
  13. def turnout_percent
  14. @ballot_papers_issued.to_f / @electorate.to_f * 100.0
  15. end
  16. def total_rejected_ballots
  17. if @rejected_no_official_mark
  18. @rejected_no_official_mark + \
  19. @rejected_too_many_candidates + \
  20. @rejected_identifiable_voter + \
  21. @rejected_blank_or_uncertain
  22. else
  23. nil
  24. end
  25. end
  26. def valid_ballot_papers
  27. self.total_rejected_ballots ? @ballot_papers_issued - self.total_rejected_ballots : nil
  28. end
  29. def successful_candidacies # Candidacies where the candidate was elected
  30. Candidacy.all(:election => @election, :district => @district, :order => [:position], :limit => @seats)
  31. end
  32. belongs_to :election
  33. belongs_to :district
  34. end
  35. class PollingStation
  36. include DataMapper::Resource
  37. property :id, String, :key => true, :length => 2 # e.g. "KA"
  38. property :name, String, :length => 255#, :required => true
  39. property :address, String, :length => 255#, :required => true
  40. property :postcode, String#, :required => true
  41. property :easting, Float, :required => true
  42. property :northing, Float, :required => true
  43. property :lat, Float, :required => true
  44. property :lng, Float, :required => true
  45. has n, :postcodes
  46. end
  47. class Postcode
  48. include DataMapper::Resource
  49. # Postcode natural key, uppercase with space, eg. "SM1 1EA"
  50. # Column names derived from Ordnance Survey CodePoint Open
  51. property :postcode, String, :key => true
  52. property :positional_quality_indicator, Integer
  53. property :eastings, Integer, :required => true
  54. property :northings, Integer, :required => true
  55. property :country_code, String, :required => true
  56. property :nhs_regional_ha_code, String, :required => true
  57. property :nhs_ha_code, String, :required => true
  58. property :admin_county_code, String # NULL within Greater London
  59. property :admin_district_code, String, :required => true # e.g. London Borough of Sutton
  60. property :admin_ward_code, String, :required => true # e.g. Sutton Central
  61. property :lat, Float, :required => true
  62. property :lng, Float, :required => true
  63. property :ward_id, Integer, :required => true # Sutton Council
  64. property :constituency_id, Integer, :required => false # UK Parliament
  65. property :polling_station_id, String, :length => 2
  66. belongs_to :district, :child_key => [:ward_id]
  67. belongs_to :polling_station
  68. def self.finder(postcode)
  69. postcode = postcode.strip.upcase
  70. if o = self.get(postcode)
  71. return o
  72. end
  73. result = Pat.get(postcode)
  74. unless result.code == 404
  75. # cache API result
  76. self.create(
  77. :postcode => postcode,
  78. :lat => result['geo']['lat'],
  79. :lng => result['geo']['lng'],
  80. :district_name => result['administrative']['district']['title'],
  81. :district_code => result['administrative']['district']['uri'].match(/.+\/(.+)$/)[1],
  82. :ward_name => result['administrative']['ward']['title'],
  83. :ward_code => result['administrative']['ward']['uri'].match(/.+\/(.+)$/)[1]
  84. )
  85. else
  86. # invalid postcode
  87. nil
  88. end
  89. end
  90. end
  91. class Candidate
  92. include DataMapper::Resource
  93. property :id, Serial
  94. property :forenames, String, :required => true
  95. property :surname, String, :required => true, :index => true
  96. has n, :candidacies
  97. def short_name
  98. @forenames.split(' ')[0] + ' ' + @surname
  99. end
  100. def name
  101. @forenames + ' ' + @surname
  102. end
  103. def url
  104. "/candidates/" + @id.to_s
  105. end
  106. end
  107. class DeletedCandidate
  108. include DataMapper::Resource
  109. property :old_candidate_id, Integer, :key => true # ID of candidate that has been merged/deleted
  110. property :candidate_id, Integer, :required => true # ID of candidate that has been kept
  111. end
  112. class Candidacy
  113. include DataMapper::Resource
  114. property :id, Serial
  115. property :election_id, Integer, :required => true
  116. property :candidate_id, Integer, :required => true
  117. property :party_id, Integer
  118. property :district_id, Integer, :required => true
  119. property :votes, Integer
  120. property :address, String, :length => 200
  121. property :postcode, String
  122. property :position, Integer # Position of this candidate in this district. (1..n)
  123. property :seats, Integer # Number of seats won by this candidacy (0 or 1)
  124. property :labcoop, Boolean, :default => false # Candidacy is for joint Labour/Co-op party
  125. belongs_to :election
  126. belongs_to :candidate
  127. belongs_to :party
  128. belongs_to :district
  129. end
  130. class Campaign
  131. include DataMapper::Resource
  132. property :party_id, Integer, :key => true
  133. property :election_id, Integer, :key => true
  134. property :party_url, String, :length => 255
  135. property :manifesto_html_url, String, :length => 255
  136. property :manifesto_pdf_url, String, :length => 255
  137. belongs_to :party
  138. belongs_to :election
  139. end
  140. class Election
  141. include DataMapper::Resource
  142. property :id, Serial
  143. property :body_id, Integer, :required => true
  144. property :d, Date, :required => true, :index => true
  145. property :reason, String, :length => 255
  146. property :kind, String, :length => 255
  147. has n, :candidacies
  148. has n, :polls
  149. belongs_to :body
  150. has n, :campaigns
  151. def self.past
  152. self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
  153. end
  154. def self.future
  155. self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
  156. end
  157. # electorate and ballot_papers_issued assume there's a Poll object for every district in this election
  158. def electorate
  159. Poll.sum(:electorate, :election => self)
  160. end
  161. def ballot_papers_issued
  162. Poll.sum(:ballot_papers_issued, :election => self)
  163. end
  164. end
  165. class District
  166. include DataMapper::Resource
  167. property :id, Serial
  168. property :body_id, Integer, :required => true
  169. property :name, String, :length => 255, :required => true
  170. property :slug, String
  171. property :seats, Integer
  172. property :ons_district_code, String
  173. belongs_to :body
  174. has n, :postcodes, :child_key => [:ward_id]
  175. has n, :polls
  176. def self.slugify(name)
  177. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  178. end
  179. end
  180. class Body
  181. include DataMapper::Resource
  182. property :id, Serial
  183. property :name, String, :length => 255, :required => true
  184. property :district_name, String, :length => 255, :required => true # singular
  185. property :districts_name, String, :length => 255, :required => true # plural
  186. property :slug, String, :length => 255
  187. has n, :elections
  188. has n, :districts
  189. end
  190. class Party
  191. include DataMapper::Resource
  192. property :id, Serial
  193. property :name, String, :required => true
  194. property :colour, String
  195. has n, :candidacies
  196. has n, :campaigns
  197. end
  198. DataMapper.setup(:default, ENV['DATABASE_URL'] || "postgres://postgres@localhost:5432/suttonelections")
  199. DataMapper.auto_upgrade!