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 |