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 6.5 KiB

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