validates_as_uk_postcode 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.mdown +54 -0
- data/init.rb +1 -0
- data/lib/rails2.rb +27 -0
- data/lib/rails3.rb +27 -0
- data/lib/validates_as_uk_postcode.rb +7 -0
- data/test/rails2/models/abstract_model.rb +5 -0
- data/test/rails2/test_helper.rb +20 -0
- data/test/rails2/validates_as_uk_postcode_test.rb +69 -0
- data/test/rails3/models/abstract_model.rb +5 -0
- data/test/rails3/test_helper.rb +20 -0
- data/test/rails3/validates_as_uk_postcode_test.rb +69 -0
- metadata +73 -0
data/README.mdown
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Validates As UK Postcode (version 2.0)
|
2
|
+
|
3
|
+
This Ruby on Rails plugin implements an ActiveRecord validation macro to allow validating of UK Postcodes. It is based on the following regular expression.
|
4
|
+
|
5
|
+
http://www.govtalk.gov.uk/gdsc/html/frames/PostCode.htm
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
gem install validates_as_uk_postcode
|
10
|
+
|
11
|
+
### Rails 2.x
|
12
|
+
|
13
|
+
# environment.rb
|
14
|
+
config.gem "validates_as_uk_postcode"
|
15
|
+
|
16
|
+
### Rails 3
|
17
|
+
|
18
|
+
# Gemfile
|
19
|
+
gem "validates_as_uk_postcode"
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
|
24
|
+
### Rails 2.x
|
25
|
+
|
26
|
+
class MyClass < ActiveRecord::Base
|
27
|
+
validates_as_uk_postcode :postcode
|
28
|
+
end
|
29
|
+
|
30
|
+
### Rails 3
|
31
|
+
|
32
|
+
class MyClass < ActiveRecord::Base
|
33
|
+
validates :postcode, :uk_postcode => true
|
34
|
+
end
|
35
|
+
|
36
|
+
## Authors
|
37
|
+
|
38
|
+
**Stephen Rushe** - http://deeden.co.uk
|
39
|
+
**Dan Kubb** - http://autopilotmarketing.com
|
40
|
+
**David Rice** - http://davidjrice.co.uk
|
41
|
+
|
42
|
+
## License
|
43
|
+
|
44
|
+
|
45
|
+
This code is released under a Creative Commons Attribution-Share Alike
|
46
|
+
3.0 Unported License. The license can be seen here:
|
47
|
+
|
48
|
+
http://creativecommons.org/licenses/by-sa/3.0/
|
49
|
+
|
50
|
+
The original version of the code (see History) was released under the
|
51
|
+
Creative Commons Attribution-Share Alike 2.5 License, which can be seen
|
52
|
+
at:
|
53
|
+
|
54
|
+
http://creativecommons.org/licenses/by-sa/2.5/
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'validates_as_uk_postcode'
|
data/lib/rails2.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module ValidatesAsUKPostcode
|
2
|
+
module Postcodes
|
3
|
+
UK = begin
|
4
|
+
an_naa_or_ann_naa = '^[A-PR-UWYZ]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
5
|
+
aan_naa_or_aann_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
6
|
+
ana_naa = '^[A-PR-UWYZ]{1}\d[A-HJKSTUW]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
7
|
+
aana_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d[ABEHMNPRVWXY]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
8
|
+
historic_code="GIR\s?0AA"
|
9
|
+
postcode_spec = "#{an_naa_or_ann_naa}|#{aan_naa_or_aann_naa}|#{ana_naa}|#{aana_naa}|#{historic_code}"
|
10
|
+
pattern = /#{postcode_spec}/i
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Rails2
|
15
|
+
|
16
|
+
def validates_as_uk_postcode(*attr_names)
|
17
|
+
configuration = {
|
18
|
+
:message => 'is an invalid uk postcode',
|
19
|
+
:with => Postcodes::UK,
|
20
|
+
:allow_nil => true }
|
21
|
+
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
|
22
|
+
|
23
|
+
validates_format_of attr_names, configuration
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/rails3.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_model'
|
3
|
+
|
4
|
+
module ValidatesAsUKPostcode
|
5
|
+
module Postcodes
|
6
|
+
UK = begin
|
7
|
+
an_naa_or_ann_naa = '^[A-PR-UWYZ]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
8
|
+
aan_naa_or_aann_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d{1,2}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
9
|
+
ana_naa = '^[A-PR-UWYZ]{1}\d[A-HJKSTUW]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
10
|
+
aana_naa = '^[A-PR-UWYZ]{1}[A-HK-Y]{1}\d[ABEHMNPRVWXY]{1}\s?\d[ABD-HJLNP-UWXYZ]{2}$'
|
11
|
+
historic_code="GIR\s?0AA"
|
12
|
+
postcode_spec = "#{an_naa_or_ann_naa}|#{aan_naa_or_aann_naa}|#{ana_naa}|#{aana_naa}|#{historic_code}"
|
13
|
+
pattern = /#{postcode_spec}/i
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Rails3
|
18
|
+
extend ActiveSupport::Concern
|
19
|
+
|
20
|
+
class PostcodeValidator < ActiveModel::EachValidator
|
21
|
+
def validate_each(object, attribute, value)
|
22
|
+
object.errors.add(attribute, "is an invalid UK postcode") unless value =~ Postcodes::UK
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
gem 'rails', '2.3.8'
|
4
|
+
|
5
|
+
require 'sqlite3'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'active_record'
|
8
|
+
require 'active_record/base'
|
9
|
+
|
10
|
+
ActiveRecord::Migration.verbose = false
|
11
|
+
ActiveRecord::Base.establish_connection(
|
12
|
+
"adapter" => "sqlite3",
|
13
|
+
"database" => ":memory:"
|
14
|
+
)
|
15
|
+
|
16
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'rails2.rb')
|
17
|
+
|
18
|
+
ActiveRecord::Base.send(:extend, ValidatesAsUKPostcode::Rails2)
|
19
|
+
|
20
|
+
autoload :AbstractModel, File.join(File.dirname(__FILE__), 'models', 'abstract_model.rb')
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test_helper.rb'
|
2
|
+
|
3
|
+
class ValidatesAsUkPostcodeTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
ActiveRecord::Schema.define(:version => 1) do
|
7
|
+
create_table :abstract_models, :force => true do |t|
|
8
|
+
t.string :postcode
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
ActiveRecord::Base.connection.drop_table(:abstract_models)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_invalid_postcodes
|
18
|
+
postcodes = [
|
19
|
+
'Q1 1AA', 'V1 1AA', 'X1 1AA', 'M1 CAA', 'M1 IAA', 'M1 KAA', 'M1 MAA', 'M1 OAA', 'M1 VAA',
|
20
|
+
|
21
|
+
'Q60 1NW', 'V60 1NW', 'X60 1NW', 'M60 1CW', 'M60 1IW', 'M60 1KW', 'M60 1MW', 'M60 1OW',
|
22
|
+
'M60 1VW', 'M60 1NC', 'M60 1NI', 'M60 1NK', 'M60 1NM', 'M60 1NO', 'M60 1NV',
|
23
|
+
|
24
|
+
'QR2 6XH', 'VR2 6XH', 'XR2 6XH', 'CI2 6XH', 'CJ2 6XH', 'CZ2 6XH', 'CR2 6CH', 'CR2 6IH',
|
25
|
+
'CR2 6KH', 'CR2 6MH', 'CR2 6OH', 'CR2 6VH', 'CR2 6XC', 'CR2 6XI', 'CR2 6XK', 'CR2 6XM',
|
26
|
+
'CR2 6XO', 'CR2 6XV',
|
27
|
+
|
28
|
+
'QN55 1PT', 'VN55 1PT', 'XN55 1PT', 'DI55 1PT', 'DJ55 1PT', 'DZ55 1PT', 'DN55 1CT',
|
29
|
+
'DN55 1IT', 'DN55 1KT', 'DN55 1MT', 'DN55 1OT', 'DN55 1VT', 'DN55 1PC', 'DN55 1PI',
|
30
|
+
'DN55 1PK', 'DN55 1PM', 'DN55 1PO', 'DN55 1PV',
|
31
|
+
|
32
|
+
'Q1A 1HQ', 'V1A 1HQ', 'X1A 1HQ', 'W1I 1HQ', 'W1L 1HQ', 'W1M 1HQ', 'W1N 1HQ', 'W1O 1HQ',
|
33
|
+
'W1P 1HQ', 'W1Q 1HQ', 'W1R 1HQ', 'W1V 1HQ', 'W1X 1HQ', 'W1Y 1HQ', 'W1Z 1HQ', 'W1A 1CQ',
|
34
|
+
'W1A 1IQ', 'W1A 1KQ', 'W1A 1MQ', 'W1A 1OQ', 'W1A 1VQ', 'W1A 1HC', 'W1A 1HI', 'W1A 1HK',
|
35
|
+
'W1A 1HM', 'W1A 1HO', 'W1A 1HV',
|
36
|
+
|
37
|
+
'QC1A 1BB', 'VC1A 1BB', 'XC1A 1BB', 'EI1A 1BB', 'EJ1A 1BB', 'EZ1A 1BB', 'EC1C 1BB',
|
38
|
+
'EC1D 1BB', 'EC1F 1BB', 'EC1G 1BB', 'EC1I 1BB', 'EC1J 1BB', 'EC1K 1BB', 'EC1L 1BB',
|
39
|
+
'EC1O 1BB', 'EC1Q 1BB', 'EC1S 1BB', 'EC1T 1BB', 'EC1U 1BB', 'EC1Z 1BB', 'EC1A 1IB',
|
40
|
+
'EC1A 1MB', 'EC1A 1OB', 'EC1A 1VB', 'EC1A 1BC', 'EC1A 1BI', 'EC1A 1BK', 'EC1A 1BM',
|
41
|
+
'EC1A 1BO', 'EC1A 1BV',
|
42
|
+
]
|
43
|
+
postcodes.each do |postcode|
|
44
|
+
assert !AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be illegal."
|
45
|
+
assert !AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be illegal."
|
46
|
+
assert !AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be illegal."
|
47
|
+
assert !AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be illegal."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_valid_postcodes
|
52
|
+
postcodes = [
|
53
|
+
'M1 1AA',
|
54
|
+
'M60 1NW',
|
55
|
+
'CR2 6XH',
|
56
|
+
'DN55 1PT',
|
57
|
+
'W1A 1HQ',
|
58
|
+
'EC1A 1BB',
|
59
|
+
'BT9 7JL',
|
60
|
+
'GIR 0AA',
|
61
|
+
]
|
62
|
+
postcodes.each do |postcode|
|
63
|
+
assert AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be legal."
|
64
|
+
assert AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be legal."
|
65
|
+
assert AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be legal."
|
66
|
+
assert AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be legal."
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
gem 'rails', '3.0.5'
|
4
|
+
|
5
|
+
require 'sqlite3'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'active_record'
|
8
|
+
require 'active_record/base'
|
9
|
+
|
10
|
+
ActiveRecord::Migration.verbose = false
|
11
|
+
ActiveRecord::Base.establish_connection(
|
12
|
+
"adapter" => "sqlite3",
|
13
|
+
"database" => ":memory:"
|
14
|
+
)
|
15
|
+
|
16
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'rails3.rb')
|
17
|
+
|
18
|
+
ActiveRecord::Base.send(:include, ValidatesAsUKPostcode::Rails3)
|
19
|
+
|
20
|
+
autoload :AbstractModel, File.join(File.dirname(__FILE__), 'models', 'abstract_model.rb')
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test_helper.rb'
|
2
|
+
|
3
|
+
class ValidatesAsUkPostcodeTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
ActiveRecord::Schema.define(:version => 1) do
|
7
|
+
create_table :abstract_models, :force => true do |t|
|
8
|
+
t.string :postcode
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
ActiveRecord::Base.connection.drop_table(:abstract_models)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_invalid_postcodes
|
18
|
+
postcodes = [
|
19
|
+
'Q1 1AA', 'V1 1AA', 'X1 1AA', 'M1 CAA', 'M1 IAA', 'M1 KAA', 'M1 MAA', 'M1 OAA', 'M1 VAA',
|
20
|
+
|
21
|
+
'Q60 1NW', 'V60 1NW', 'X60 1NW', 'M60 1CW', 'M60 1IW', 'M60 1KW', 'M60 1MW', 'M60 1OW',
|
22
|
+
'M60 1VW', 'M60 1NC', 'M60 1NI', 'M60 1NK', 'M60 1NM', 'M60 1NO', 'M60 1NV',
|
23
|
+
|
24
|
+
'QR2 6XH', 'VR2 6XH', 'XR2 6XH', 'CI2 6XH', 'CJ2 6XH', 'CZ2 6XH', 'CR2 6CH', 'CR2 6IH',
|
25
|
+
'CR2 6KH', 'CR2 6MH', 'CR2 6OH', 'CR2 6VH', 'CR2 6XC', 'CR2 6XI', 'CR2 6XK', 'CR2 6XM',
|
26
|
+
'CR2 6XO', 'CR2 6XV',
|
27
|
+
|
28
|
+
'QN55 1PT', 'VN55 1PT', 'XN55 1PT', 'DI55 1PT', 'DJ55 1PT', 'DZ55 1PT', 'DN55 1CT',
|
29
|
+
'DN55 1IT', 'DN55 1KT', 'DN55 1MT', 'DN55 1OT', 'DN55 1VT', 'DN55 1PC', 'DN55 1PI',
|
30
|
+
'DN55 1PK', 'DN55 1PM', 'DN55 1PO', 'DN55 1PV',
|
31
|
+
|
32
|
+
'Q1A 1HQ', 'V1A 1HQ', 'X1A 1HQ', 'W1I 1HQ', 'W1L 1HQ', 'W1M 1HQ', 'W1N 1HQ', 'W1O 1HQ',
|
33
|
+
'W1P 1HQ', 'W1Q 1HQ', 'W1R 1HQ', 'W1V 1HQ', 'W1X 1HQ', 'W1Y 1HQ', 'W1Z 1HQ', 'W1A 1CQ',
|
34
|
+
'W1A 1IQ', 'W1A 1KQ', 'W1A 1MQ', 'W1A 1OQ', 'W1A 1VQ', 'W1A 1HC', 'W1A 1HI', 'W1A 1HK',
|
35
|
+
'W1A 1HM', 'W1A 1HO', 'W1A 1HV',
|
36
|
+
|
37
|
+
'QC1A 1BB', 'VC1A 1BB', 'XC1A 1BB', 'EI1A 1BB', 'EJ1A 1BB', 'EZ1A 1BB', 'EC1C 1BB',
|
38
|
+
'EC1D 1BB', 'EC1F 1BB', 'EC1G 1BB', 'EC1I 1BB', 'EC1J 1BB', 'EC1K 1BB', 'EC1L 1BB',
|
39
|
+
'EC1O 1BB', 'EC1Q 1BB', 'EC1S 1BB', 'EC1T 1BB', 'EC1U 1BB', 'EC1Z 1BB', 'EC1A 1IB',
|
40
|
+
'EC1A 1MB', 'EC1A 1OB', 'EC1A 1VB', 'EC1A 1BC', 'EC1A 1BI', 'EC1A 1BK', 'EC1A 1BM',
|
41
|
+
'EC1A 1BO', 'EC1A 1BV',
|
42
|
+
]
|
43
|
+
postcodes.each do |postcode|
|
44
|
+
assert !AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be illegal."
|
45
|
+
assert !AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be illegal."
|
46
|
+
assert !AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be illegal."
|
47
|
+
assert !AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be illegal."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_valid_postcodes
|
52
|
+
postcodes = [
|
53
|
+
'M1 1AA',
|
54
|
+
'M60 1NW',
|
55
|
+
'CR2 6XH',
|
56
|
+
'DN55 1PT',
|
57
|
+
'W1A 1HQ',
|
58
|
+
'EC1A 1BB',
|
59
|
+
'BT9 7JL',
|
60
|
+
'GIR 0AA',
|
61
|
+
]
|
62
|
+
postcodes.each do |postcode|
|
63
|
+
assert AbstractModel.new(:postcode => postcode).valid?, "#{postcode} should be legal."
|
64
|
+
assert AbstractModel.new(:postcode => postcode.downcase).valid?, "#{postcode.downcase} should be legal."
|
65
|
+
assert AbstractModel.new(:postcode => postcode.gsub(' ', '')).valid?, "#{postcode} (with no spaces) should be legal."
|
66
|
+
assert AbstractModel.new(:postcode => postcode.downcase.gsub(' ', '')).valid?, "#{postcode.downcase} (with no spaces) should be legal."
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: validates_as_uk_postcode
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 2
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 2.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Steven Rushe
|
13
|
+
- David Rice
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-12 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: A library for validating uk postcodes
|
23
|
+
email:
|
24
|
+
- me@davidjrice.co.uk
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files:
|
30
|
+
- README.mdown
|
31
|
+
files:
|
32
|
+
- init.rb
|
33
|
+
- lib/rails2.rb
|
34
|
+
- lib/rails3.rb
|
35
|
+
- lib/validates_as_uk_postcode.rb
|
36
|
+
- README.mdown
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/davidjrice/validates_as_uk_postcode
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
segments:
|
51
|
+
- 0
|
52
|
+
version: "0"
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.3.6
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Validates a field is a valid UK postcode
|
67
|
+
test_files:
|
68
|
+
- test/rails2/models/abstract_model.rb
|
69
|
+
- test/rails2/test_helper.rb
|
70
|
+
- test/rails2/validates_as_uk_postcode_test.rb
|
71
|
+
- test/rails3/models/abstract_model.rb
|
72
|
+
- test/rails3/test_helper.rb
|
73
|
+
- test/rails3/validates_as_uk_postcode_test.rb
|