| 1require_dependency 'constituency/api_client' | |
| 2require_dependency 'constituency/api_query' | |
| 4class Constituency < ActiveRecord::Base | |
| 5 MP_URL = "http://www.parliament.uk/biographies/commons" | |
| 7 has_many :signatures, primary_key: :external_id | |
| 8 has_many :petitions, through: :signatures | |
| 10 validates :name, presence: true, length: { maximum: 100 } | |
| 11 validates :external_id, presence: true, length: { maximum: 30 } | |
| 12 validates :ons_code, presence: true, format: %r[\A(?:E|W|S|N)\d{8}\z] | |
| 13 validates :mp_id, length: { maximum: 30 } | |
| 14 validates :mp_name, length: { maximum: 100 } | |
| 15 validates :example_postcode, presence: true | |
| 17 delegate :query, :example_postcodes, to: "self.class" | |
| 19 before_validation unless: :example_postcode? do | |
| 20 self.example_postcode = example_postcodes[ons_code] | |
| 21 end | |
| 23 before_validation if: :name_changed? do | |
| 24 self.slug = name.parameterize | |
| 25 end | |
| 27 validate on: :update, if: :example_postcode_changed? do | |
| 28    results = query.fetch(example_postcode)
 | |
| 29    attributes = results.first
 | |
| 31 if attributes.nil? || external_id != attributes[:external_id] | |
| 32 errors.add :example_postcode, :invalid | |
| 33 end | |
| 34 end | |
| 36 class << self | |
| 37 def by_ons_code | |
| 38 order(ons_code: :asc) | |
| 39 end | |
| 
 | 41 def find_by_postcode(postcode) | 
| 42 return if Site.disable_constituency_api? | |
| 44      results = query.fetch(postcode)
 | |
| 
 | 46 if attributes = results.first | 
| 47 constituency = find_or_initialize_by(external_id: attributes[:external_id]) | |
| 48        constituency.attributes = attributes
 | |
| 49 if constituency.changed? || constituency.new_record? | |
| 50          constituency.save!
 | |
| 51 end | |
| 53        constituency
 | |
| 54 end | |
| 55 end | |
| 57 def refresh! | |
| 58      find_each { |c| c.refresh! }
 | |
| 59 end | |
| 61 def query | |
| 62 ApiQuery.new | |
| 63 end | |
| 65 def example_postcodes | |
| 66 @example_postcodes ||= YAML.load_file(Rails.root.join("data", "example_postcodes.yml")) | |
| 67 end | |
| 68 end | |
| 70 def sitting_mp? | |
| 71    mp_id?
 | |
| 72 end | |
| 74 def mp_url | |
| 75 "#{MP_URL}/#{mp_name.parameterize}/#{mp_id}" | |
| 76 end | |
| 78 def to_param | |
| 79    slug
 | |
| 80 end | |
| 
 | 82 def refresh! | 
| 83 return unless example_postcode? | |
| 85    results = query.fetch(example_postcode)
 | |
| 86    attributes = results.first
 | |
| 88 if attributes.nil? | |
| 89      raise empty_results_exception
 | |
| 90 elsif external_id != attributes[:external_id] | |
| 91      raise mismatched_results_exception(attributes)
 | |
| 92 else | |
| 93 self.mp_id = attributes[:mp_id] | |
| 94 self.mp_name = attributes[:mp_name] | |
| 95 self.mp_date = attributes[:mp_date] | |
| 97 save! if changed? | |
| 98 end | |
| 99 end | |
| 101  private
 | |
| 103 def empty_results_exception | |
| 105 empty results from API when refreshing | |
| 106 with example_postcode #{example_postcode.inspect} | |
| 107 ERROR | |
| 108 end | |
| 110 def mismatched_results_exception(attributes) | |
| 112 mismatched constituencies when refreshing | |
| 113 with example postcode #{example_postcode.inspect} | |
| 114 - expected: #{external_id}, actual: #{attributes[:external_id]} | |
| 115 ERROR | |
| 116 end | |
| 117end |