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.0 KiB

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