Election results in the London Borough of Sutton.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

models.rb 7.2 KiB

13 år sedan
13 år sedan
13 år sedan
13 år sedan
13 år sedan
11 år sedan
13 år sedan
13 år sedan
13 år sedan
13 år sedan
11 år sedan
13 år sedan
13 år sedan
13 år sedan
13 år sedan
13 år sedan
13 år sedan
13 år sedan
13 år sedan
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. has n, :candidacies
  77. def short_name
  78. @forenames.split(' ')[0] + ' ' + @surname
  79. end
  80. def name
  81. @forenames + ' ' + @surname
  82. end
  83. end
  84. class DeletedCandidate
  85. include DataMapper::Resource
  86. property :old_candidate_id, Integer, :key => true # ID of candidate that has been merged/deleted
  87. property :candidate_id, Integer, :required => true # ID of candidate that has been kept
  88. end
  89. class Candidacy
  90. include DataMapper::Resource
  91. property :id, Serial
  92. property :election_id, Integer, :required => true
  93. property :candidate_id, Integer, :required => true
  94. property :party_id, Integer
  95. property :district_id, Integer, :required => true
  96. property :votes, Integer
  97. property :address, String, :length => 200
  98. property :postcode, String
  99. property :position, Integer # Position of this candidate in this district. (1..n)
  100. property :seats, Integer # Number of seats won by this candidacy (0 or 1)
  101. property :labcoop, Boolean, :default => false # Candidacy is for joint Labour/Co-op party
  102. belongs_to :election
  103. belongs_to :candidate
  104. belongs_to :party
  105. belongs_to :district
  106. end
  107. class Campaign
  108. include DataMapper::Resource
  109. property :party_id, Integer, :key => true
  110. property :election_id, Integer, :key => true
  111. property :party_url, String, :length => 255
  112. property :manifesto_html_url, String, :length => 255
  113. property :manifesto_pdf_url, String, :length => 255
  114. belongs_to :party
  115. belongs_to :election
  116. end
  117. class Election
  118. include DataMapper::Resource
  119. property :id, Serial
  120. property :body_id, Integer, :required => true
  121. property :d, Date, :required => true, :index => true
  122. property :reason, String, :length => 255
  123. property :kind, String, :length => 255
  124. has n, :candidacies
  125. has n, :polls
  126. belongs_to :body
  127. has n, :campaigns
  128. def self.past
  129. self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
  130. end
  131. def self.future
  132. self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
  133. end
  134. # electorate and ballot_papers_issued assume there's a Poll object for every district in this election
  135. def electorate
  136. Poll.sum(:electorate, :election => self)
  137. end
  138. def ballot_papers_issued
  139. Poll.sum(:ballot_papers_issued, :election => self)
  140. end
  141. end
  142. class District
  143. include DataMapper::Resource
  144. property :id, Serial
  145. property :body_id, Integer, :required => true
  146. property :name, String, :length => 255, :required => true
  147. property :slug, String
  148. property :seats, Integer
  149. property :ons_district_code, String
  150. belongs_to :body
  151. has n, :postcodes, :child_key => [:ward_id]
  152. has n, :polls
  153. def self.slugify(name)
  154. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  155. end
  156. end
  157. class Body
  158. include DataMapper::Resource
  159. property :id, Serial
  160. property :name, String, :length => 255, :required => true
  161. property :district_name, String, :length => 255, :required => true # singular
  162. property :districts_name, String, :length => 255, :required => true # plural
  163. property :slug, String, :length => 255
  164. has n, :elections
  165. has n, :districts
  166. end
  167. class Party
  168. include DataMapper::Resource
  169. property :id, Serial
  170. property :name, String, :required => true
  171. property :colour, String
  172. has n, :candidacies
  173. has n, :campaigns
  174. end
  175. DataMapper.setup(:default, ENV['DATABASE_URL'] || "postgres://postgres@localhost:5432/suttonelections")
  176. DataMapper.auto_upgrade!