5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/addressing/model.rb', line 5
def validates_address_format(
fields: [:country_code, :administrative_area, :locality, :dependent_locality, :postal_code, :sorting_code, :address_line1, :address_line2, :organization, :given_name, :additional_name, :family_name, :locale], field_overrides: nil, verify_postal_code: true, **options
)
fields = Array(fields)
field_overrides ||= FieldOverrides.new({})
options[:if] ||= -> { fields.any? { |f| changes.key?(f.to_s) } } unless options[:unless]
class_eval do
validate :verify_address_format, **options
define_method :verify_address_format do
values = fields.each_with_object({}) { |f, v| v[f] = send(f) if respond_to?(f) }
address = Address.new(**values)
return unless address.country_code.present?
address_format = AddressFormat.get(address.country_code)
address_format.used_fields
return unless address.country_code.present?
address_format = AddressFormat.get(address.country_code)
address_format.used_fields
AddressFormatHelper.required_fields(address_format, field_overrides).each do |required_field|
next unless address.send(required_field).blank?
errors.add(required_field, "should not be blank")
end
used_fields = address_format.used_fields - field_overrides.hidden_fields
unused_fields = AddressField.all.values - used_fields
unused_fields.each do |unused_field|
next if address.send(unused_field).blank?
errors.add(unused_field, "should be blank")
end
subdivisions = verify_subdivisions(address, address_format, field_overrides)
verify_postal_code(address.postal_code, subdivisions, address_format) if used_fields.include?(AddressField::POSTAL_CODE) && verify_postal_code
end
define_method :verify_subdivisions do |address, address_format, field_overrides|
return [] if address_format.subdivision_depth < 1
subdivisions, _parents = address_format.used_subdivision_fields.each_with_index.inject([[], []]) do |(subdivisions, parents), (field, index)|
break [subdivisions, parents] if address.send(field).blank? || field_overrides.hidden_fields.include?(field)
parents << ((index > 0) ? address.send(address_format.used_subdivision_fields[index - 1]) : address_format.country_code)
subdivision = Subdivision.get(address.send(field), parents)
if subdivision.nil?
errors.add(field, "should be valid")
break [subdivisions, parents]
end
subdivisions << subdivision
break [subdivisions, parents] if subdivision.children.empty?
[subdivisions, parents]
end
subdivisions
end
define_method :verify_postal_code do |postal_code, subdivisions, address_format|
return if postal_code.blank?
pattern = subdivisions.inject(address_format.postal_code_pattern) do |pattern, subdivision|
subdivision_pattern = subdivision.postal_code_pattern
next pattern if subdivision_pattern.blank?
subdivision_pattern
end
if pattern
match = postal_code.match(Regexp.new(pattern.gsub("\\\\", "\\").to_s, "i"))
if match.nil? || match[0] != postal_code
errors.add(AddressField::POSTAL_CODE, "should be valid")
nil
end
end
end
end
end
|