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.
 
 
 
 

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