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.
 
 
 
 

226 lines
6.6 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. end
  13. class Postcode
  14. include DataMapper::Resource
  15. # Postcode natural key, uppercase with space, eg. "SM1 1EA"
  16. property :postcode, String, :key => true
  17. property :created_at, DateTime
  18. property :updated_at, DateTime
  19. property :lat, Float, :required => true
  20. property :lng, Float, :required => true
  21. property :district_name, String, :required => true
  22. property :district_code, String, :required => true
  23. property :ward_name, String, :required => true
  24. property :ward_code, String, :required => true
  25. def self.finder(postcode)
  26. postcode = postcode.strip.upcase
  27. if o = self.get(postcode)
  28. return o
  29. end
  30. result = Pat.get(postcode)
  31. unless result.code == 404
  32. # cache API result
  33. self.create(
  34. :postcode => postcode,
  35. :lat => result['geo']['lat'],
  36. :lng => result['geo']['lng'],
  37. :district_name => result['administrative']['district']['title'],
  38. :district_code => result['administrative']['district']['uri'].match(/.+\/(.+)$/)[1],
  39. :ward_name => result['administrative']['ward']['title'],
  40. :ward_code => result['administrative']['ward']['uri'].match(/.+\/(.+)$/)[1]
  41. )
  42. else
  43. # invalid postcode
  44. nil
  45. end
  46. end
  47. end
  48. class Candidate
  49. include DataMapper::Resource
  50. property :id, Serial
  51. property :forenames, String, :required => true
  52. property :surname, String, :required => true, :index => true
  53. property :sex, String
  54. has n, :candidacies
  55. def short_name
  56. @forenames.split(' ')[0] + ' ' + @surname
  57. end
  58. def name
  59. @forenames + ' ' + @surname
  60. end
  61. end
  62. class Candidacy
  63. include DataMapper::Resource
  64. property :id, Serial
  65. property :election_id, Integer, :required => true
  66. property :candidate_id, Integer, :required => true
  67. property :party_id, Integer
  68. property :district_id, Integer, :required => true
  69. property :votes, Integer
  70. property :address, String, :length => 200
  71. property :postcode, String
  72. property :position, Integer # Position of this candidate in this district. (1..n)
  73. property :seats, Integer # Number of seats won by this candidacy (0 or 1)
  74. belongs_to :election
  75. belongs_to :candidate
  76. belongs_to :party
  77. belongs_to :district
  78. end
  79. class Election
  80. include DataMapper::Resource
  81. property :id, Serial
  82. property :body_id, Integer, :required => true
  83. property :d, Date, :required => true, :index => true
  84. property :reason, String, :length => 255
  85. property :kind, String, :length => 255
  86. has n, :candidacies
  87. belongs_to :body
  88. def self.past
  89. self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
  90. end
  91. def self.future
  92. self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
  93. end
  94. end
  95. class District
  96. include DataMapper::Resource
  97. property :id, Serial
  98. property :body_id, Integer, :required => true
  99. property :name, String, :length => 255, :required => true
  100. property :slug, String
  101. property :seats, Integer
  102. belongs_to :body
  103. def self.slugify(name)
  104. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  105. end
  106. end
  107. class Body
  108. include DataMapper::Resource
  109. property :id, Serial
  110. property :name, String, :length => 255, :required => true
  111. property :district_name, String, :length => 255, :required => true # singular
  112. property :districts_name, String, :length => 255, :required => true # plural
  113. property :slug, String, :length => 255
  114. has n, :elections
  115. has n, :districts
  116. end
  117. class Party
  118. include DataMapper::Resource
  119. property :id, Serial
  120. property :name, String, :required => true
  121. property :colour, String
  122. has n, :candidacies
  123. end
  124. # These models are now redundant
  125. class Ward
  126. include DataMapper::Resource
  127. property :id, Serial
  128. property :slug, String, :required => true
  129. property :ons_id, String, :required => true
  130. property :name, String, :required => true
  131. property :constituency_id, Integer, :required => true
  132. has n, :councilcandidates, :order => ['surname']
  133. belongs_to :constituency
  134. def self.slugify(name)
  135. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  136. end
  137. end
  138. class Councilcandidate
  139. include DataMapper::Resource
  140. property :id, Serial
  141. property :ward_id, Integer, :required => true
  142. property :party_id, Integer, :required => true
  143. property :forenames, String, :required => true
  144. property :surname, String, :required => true
  145. property :address, String, :length => 200
  146. property :postcode, String, :required => true
  147. property :votes_2010, Integer
  148. belongs_to :party
  149. belongs_to :ward
  150. end
  151. class Parliamentcandidate
  152. include DataMapper::Resource
  153. property :id, Serial
  154. property :constituency_id, Integer, :required => true
  155. property :party_id, Integer, :required => true
  156. property :forenames, String, :required => true
  157. property :surname, String, :required => true
  158. property :address, String, :length => 200
  159. property :postcode, String
  160. property :votes_2010, Integer
  161. property :votes_2005, Integer
  162. property :percent_2005, Float
  163. belongs_to :party
  164. belongs_to :constituency
  165. end
  166. class Constituency
  167. include DataMapper::Resource
  168. property :id, Serial
  169. property :name, String, :required => true
  170. has n, :wards, :order => ['name']
  171. has n, :parliamentcandidates, :order => ['surname']
  172. end
  173. DataMapper.setup(:default, ENV['DATABASE_URL'] || "postgres://postgres@localhost:5432/suttonelections")
  174. DataMapper.auto_upgrade!