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

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
14 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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 :seats, Integer
  64. belongs_to :election
  65. belongs_to :candidate
  66. belongs_to :party
  67. belongs_to :district
  68. end
  69. class Election
  70. include DataMapper::Resource
  71. property :id, Serial
  72. property :body_id, Integer, :required => true
  73. property :d, Date, :required => true
  74. property :reason, String, :length => 255
  75. property :kind, String, :length => 255
  76. has n, :candidacies
  77. belongs_to :body
  78. def self.past
  79. self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
  80. end
  81. def self.future
  82. self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
  83. end
  84. end
  85. class District
  86. include DataMapper::Resource
  87. property :id, Serial
  88. property :body_id, Integer, :required => true
  89. property :name, String, :length => 255, :required => true
  90. property :slug, String
  91. property :seats, Integer
  92. belongs_to :body
  93. def self.slugify(name)
  94. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  95. end
  96. end
  97. class Body
  98. include DataMapper::Resource
  99. property :id, Serial
  100. property :name, String, :length => 255, :required => true
  101. property :district_name, String, :length => 255, :required => true # singular
  102. property :districts_name, String, :length => 255, :required => true # plural
  103. property :slug, String, :length => 255
  104. has n, :elections
  105. has n, :districts
  106. end
  107. class Party
  108. include DataMapper::Resource
  109. property :id, Serial
  110. property :name, String, :required => true
  111. property :colour, String
  112. has n, :candidacies
  113. end
  114. # These models are now redundant
  115. class Ward
  116. include DataMapper::Resource
  117. property :id, Serial
  118. property :slug, String, :required => true
  119. property :ons_id, String, :required => true
  120. property :name, String, :required => true
  121. property :constituency_id, Integer, :required => true
  122. has n, :councilcandidates, :order => ['surname']
  123. belongs_to :constituency
  124. def self.slugify(name)
  125. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  126. end
  127. end
  128. class Councilcandidate
  129. include DataMapper::Resource
  130. property :id, Serial
  131. property :ward_id, Integer, :required => true
  132. property :party_id, Integer, :required => true
  133. property :forenames, String, :required => true
  134. property :surname, String, :required => true
  135. property :address, String, :length => 200
  136. property :postcode, String, :required => true
  137. property :votes_2010, Integer
  138. belongs_to :party
  139. belongs_to :ward
  140. end
  141. class Parliamentcandidate
  142. include DataMapper::Resource
  143. property :id, Serial
  144. property :constituency_id, Integer, :required => true
  145. property :party_id, Integer, :required => true
  146. property :forenames, String, :required => true
  147. property :surname, String, :required => true
  148. property :address, String, :length => 200
  149. property :postcode, String
  150. property :votes_2010, Integer
  151. property :votes_2005, Integer
  152. property :percent_2005, Float
  153. belongs_to :party
  154. belongs_to :constituency
  155. end
  156. class Constituency
  157. include DataMapper::Resource
  158. property :id, Serial
  159. property :name, String, :required => true
  160. has n, :wards, :order => ['name']
  161. has n, :parliamentcandidates, :order => ['surname']
  162. end
  163. DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/db/suttonelections.db")
  164. DataMapper.auto_upgrade!