Election results in the London Borough of Sutton.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

models.rb 5.9 KiB

13年前
13年前
13年前
11年前
13年前
13年前
13年前
13年前
11年前
13年前
13年前
13年前
13年前
13年前
13年前
13年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. require 'data_mapper'
  2. load '_config.rb'
  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. property :rejected_no_official_mark, Integer
  11. property :rejected_too_many_candidates, Integer
  12. property :rejected_identifiable_voter, Integer
  13. property :rejected_blank_or_uncertain, Integer
  14. def turnout_percent
  15. @ballot_papers_issued.to_f / @electorate.to_f * 100.0
  16. end
  17. def total_rejected_ballots
  18. if @rejected_no_official_mark
  19. @rejected_no_official_mark + \
  20. @rejected_too_many_candidates + \
  21. @rejected_identifiable_voter + \
  22. @rejected_blank_or_uncertain
  23. else
  24. nil
  25. end
  26. end
  27. def valid_ballot_papers
  28. self.total_rejected_ballots ? @ballot_papers_issued - self.total_rejected_ballots : nil
  29. end
  30. def successful_candidacies # Candidacies where the candidate was elected
  31. Candidacy.all(:election => @election, :district => @district, :order => [:position], :limit => @seats)
  32. end
  33. # Set candidacy.position for every candidacy in this poll
  34. # Returns array of candidacies, or false if we don't have results for this poll
  35. def set_positions
  36. # Check that every candidacy for this poll has its votes recorded (ie that the election results are known)
  37. return false if Candidacy.count(:conditions => { :district_id => @district_id, :election_id => @election_id, :votes => nil }) > 0
  38. # Get the candidacies for this poll
  39. ccys = Candidacy.all(:conditions => { :district_id => @district_id, :election_id => @election_id }, :order => [:votes.desc])
  40. puts "Found no candidacies for this poll" if ccys.size == 0
  41. position = 1
  42. ccys.each do |ccy|
  43. position <= @seats ? ccy.seats = 1 : ccy.seats = 0
  44. ccy.position = position
  45. ccy.save
  46. position += 1
  47. end
  48. ccys
  49. end
  50. belongs_to :election
  51. belongs_to :district
  52. end
  53. class Candidate
  54. include DataMapper::Resource
  55. property :id, Serial
  56. property :forenames, String, :required => true
  57. property :surname, String, :required => true, :index => true
  58. has n, :candidacies#, 'Candidacy'
  59. def short_name
  60. @forenames.split(' ')[0] + ' ' + @surname
  61. end
  62. def name
  63. @forenames + ' ' + @surname
  64. end
  65. def url
  66. "/candidates/" + @id.to_s
  67. end
  68. end
  69. class DeletedCandidate
  70. include DataMapper::Resource
  71. property :old_candidate_id, Integer, :key => true # ID of candidate that has been merged/deleted
  72. property :candidate_id, Integer, :required => true # ID of candidate that has been kept
  73. end
  74. class Candidacy
  75. include DataMapper::Resource
  76. property :id, Serial
  77. property :election_id, Integer, :required => true
  78. property :candidate_id, Integer, :required => true
  79. property :party_id, Integer
  80. property :district_id, Integer, :required => true
  81. property :votes, Integer
  82. property :address, String, :length => 200
  83. property :postcode, String
  84. property :position, Integer # Position of this candidate in this district. (1..n)
  85. property :seats, Integer # Number of seats won by this candidacy (0 or 1)
  86. property :labcoop, String, :default => '0' # Candidacy is for joint Labour/Co-op party
  87. belongs_to :election
  88. belongs_to :candidate
  89. belongs_to :party
  90. belongs_to :district
  91. end
  92. class Election
  93. include DataMapper::Resource
  94. property :id, Serial
  95. property :body_id, Integer, :required => true
  96. property :d, Date, :required => true, :index => true
  97. property :reason, String, :length => 255
  98. property :kind, String, :length => 255
  99. has n, :candidacies
  100. has n, :polls
  101. belongs_to :body
  102. def self.past
  103. self.all(:d.lt => Time.now.to_s, :order => [ :d.desc ])
  104. end
  105. def self.future
  106. self.all(:d.gte => Time.now.to_s, :order => [ :d.desc ])
  107. end
  108. # electorate and ballot_papers_issued assume there's a Poll object for every district in this election
  109. def electorate
  110. Poll.sum(:electorate, :election => self)
  111. end
  112. def ballot_papers_issued
  113. Poll.sum(:ballot_papers_issued, :election => self)
  114. end
  115. def set_positions
  116. polls.each { |p| p.set_positions }
  117. end
  118. end
  119. class District
  120. include DataMapper::Resource
  121. property :id, Serial
  122. property :body_id, Integer, :required => true
  123. property :name, String, :length => 255, :required => true
  124. property :slug, String
  125. property :ons_district_code, String
  126. belongs_to :body
  127. has n, :polls
  128. def self.slugify(name)
  129. name.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  130. end
  131. end
  132. class Body
  133. include DataMapper::Resource
  134. property :id, Serial
  135. property :name, String, :length => 255, :required => true
  136. property :district_name, String, :length => 255, :required => true # singular
  137. property :districts_name, String, :length => 255, :required => true # plural
  138. property :slug, String, :length => 255
  139. has n, :elections
  140. has n, :districts
  141. end
  142. class Party
  143. include DataMapper::Resource
  144. property :id, Serial
  145. property :name, String, :required => true
  146. property :colour, String
  147. has n, :candidacies
  148. # has n, :campaigns
  149. end
  150. DataMapper.setup(:default, ENV['DATABASE_URL'])
  151. DataMapper.repository(:default).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::UnderscoredAndPluralized
  152. DataMapper.auto_upgrade!