rails_validations 1.2 → 1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.markdown +40 -2
- data/config/locales/en.yml +6 -0
- data/config/locales/nl.yml +6 -0
- data/lib/rails_validations.rb +2 -1
- data/lib/validators/check_digit_validator.rb +18 -0
- data/lib/validators/commerce_number_validator.rb +28 -0
- data/lib/validators/postal_code_validator.rb +1 -0
- data/lib/validators/vat_number_validator.rb +32 -0
- data/spec/spec_helper.rb +10 -1
- data/spec/validations/commerce_number_spec.rb +39 -0
- data/spec/validations/postal_code_spec.rb +1 -0
- data/spec/validations/vat_number_spec.rb +41 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 951d63d5356bcdf895cef31ec5726e049079bc7a
|
4
|
+
data.tar.gz: bbfbf7c0b5e64858ad78723f1990d205aa40918b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 563d7dfa6e1f2cc9035a7c3b761f8b86a08f452b63ccc8725442f7d6abd7c60a4dc5ca28ff4f5ca2abacbf488fb0098bdae3b1bc42e41c1d6627a6f232e06449
|
7
|
+
data.tar.gz: 09f588a7881780926db041f19f4e8edce501cc1c8d12cc878f06f7bcb087f620a5502820d6eb0734c2440a1590994f85ccf63683ddeb63502cea17c4c4110330
|
data/MIT-LICENSE
CHANGED
data/README.markdown
CHANGED
@@ -6,16 +6,23 @@
|
|
6
6
|
|
7
7
|
A few extra validations for Ruby on Rails.
|
8
8
|
|
9
|
-
We try to do the
|
9
|
+
We try to do the sane thing by not being too strict, when in doubt, we accept
|
10
10
|
input as being valid. We never want to reject valid input as invalid.
|
11
11
|
|
12
12
|
For many formats doing a 100% foolproof check is not trivial, email addresses
|
13
13
|
are a famous example, but it also applies to other formats.
|
14
14
|
Regardless, you can never be sure it’s what the user *intended* anyway. For
|
15
15
|
example, email validators will accept `artin@ico.nl` as being ‘valid’, even
|
16
|
-
though my email address is `martin@lico.nl
|
16
|
+
though my email address is `martin@lico.nl`.
|
17
17
|
|
18
18
|
|
19
|
+
I18N
|
20
|
+
====
|
21
|
+
The gem includes English and Dutch error messages. If you want to translate it
|
22
|
+
to another language then copy [`config/locales/en.yml`][tr] to your project.
|
23
|
+
Please send us your translations so we can add them!
|
24
|
+
|
25
|
+
[tr]: https://github.com/bluerail/rails_validations/blob/master/config/locales/en.yml
|
19
26
|
|
20
27
|
|
21
28
|
Available validations
|
@@ -109,8 +116,39 @@ Currently implemented countries:
|
|
109
116
|
- `nl` - The Netherlands
|
110
117
|
|
111
118
|
|
119
|
+
commerce\_number
|
120
|
+
---------------
|
121
|
+
Check if this is a valid chamber of commerce identification number.
|
122
|
+
|
123
|
+
validates :commerce_number_column, commerce_number: { country: :nl }
|
124
|
+
|
125
|
+
Currently implemented countries:
|
126
|
+
|
127
|
+
- `nl` - The Netherlands
|
128
|
+
|
129
|
+
|
130
|
+
vat\_number
|
131
|
+
-----------
|
132
|
+
Check if this is a valid [VAT identification number](https://en.wikipedia.org/wiki/VAT_identification_number)
|
133
|
+
|
134
|
+
validates :vat_number_column, vat_number: { country: :nl }
|
135
|
+
|
136
|
+
Currently implemented countries:
|
137
|
+
|
138
|
+
- `nl` - The Netherlands
|
139
|
+
|
140
|
+
|
112
141
|
ChangeLog
|
113
142
|
=========
|
143
|
+
|
144
|
+
Version 1.3, 2015-05-22
|
145
|
+
-----------------------
|
146
|
+
- Add `commerce_number` validation.
|
147
|
+
- Add `vat_number` validation.
|
148
|
+
- The `postal_code` validation will now raise an error if an invalid country
|
149
|
+
code is given.
|
150
|
+
|
151
|
+
|
114
152
|
Version 1.2, 2015-03-07
|
115
153
|
-----------------------
|
116
154
|
- The IBAN check will now defaults to just a "is invalid" message, set the
|
data/config/locales/en.yml
CHANGED
@@ -27,3 +27,9 @@ en:
|
|
27
27
|
invalid: not a valid domain
|
28
28
|
max_domain_parts: only %{max} domain parts are allowed
|
29
29
|
min_domain_parts: needs to have at least %{min} domain parts
|
30
|
+
|
31
|
+
vat_number:
|
32
|
+
invalid: not a valid VAT identification number
|
33
|
+
|
34
|
+
commerce_number:
|
35
|
+
invalid: not a valid chamber of commerce number
|
data/config/locales/nl.yml
CHANGED
@@ -27,3 +27,9 @@ nl:
|
|
27
27
|
invalid: geen geldig domain
|
28
28
|
max_domain_parts: er zijn %{max} domeinstukken toegestaan
|
29
29
|
min_domain_parts: er moeten minimaal %{min} domeinstukken zijn
|
30
|
+
|
31
|
+
vat_number:
|
32
|
+
invalid: geen geldig BTW nummer
|
33
|
+
|
34
|
+
commerce_number:
|
35
|
+
invalid: geen geldig KvK nummer
|
data/lib/rails_validations.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
require 'validators/commerce_number_validator'
|
1
2
|
require 'validators/date_validator'
|
2
3
|
require 'validators/domain_validator'
|
3
4
|
require 'validators/email_validator'
|
4
5
|
require 'validators/iban_validator'
|
5
6
|
require 'validators/phone_validator'
|
6
7
|
require 'validators/postal_code_validator'
|
7
|
-
|
8
|
+
require 'validators/vat_number_validator'
|
8
9
|
|
9
10
|
I18n.load_path += Dir["#{File.dirname(__FILE__)}/../config/locales/*.yml"]
|
10
11
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Check digit for BSN, but see if we can make this more generic
|
2
|
+
#class ElevenProofValidator < ActiveModel::EachValidator
|
3
|
+
# # The eleven-proof of a BSN is as follows:
|
4
|
+
# # Given: BSN presented as ABCDEFGHI with length is 9:
|
5
|
+
# # 9xA+8xB+7xC+6xD+5xE+4xF+3xG+2xH-1xI (caveat: the minus!)
|
6
|
+
#
|
7
|
+
# def validate_each(record, attribute, value)
|
8
|
+
# return if value.to_s.empty?
|
9
|
+
#
|
10
|
+
# total = 0
|
11
|
+
# if value.to_s.length == 9
|
12
|
+
# 8.times { |x| total += value[x].to_i * (9-x) }
|
13
|
+
# total -= value[8].to_i
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# record.errors.add(attribute, I18n.t('errors.messages.eleven_proof_error')) if total.modulo(11)!=0 || value.length != 9
|
17
|
+
# end
|
18
|
+
#end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Chamber of commerce number
|
2
|
+
class CommerceNumberValidator < ActiveModel::EachValidator
|
3
|
+
# keys are ISO-3366-1 alpha2
|
4
|
+
REGEXP = {
|
5
|
+
# KvK nummer; 8 digits. Allow space, -, and . for formatting
|
6
|
+
nl: -> (v) { v.gsub(/[.\- ]/, '') =~ /\A\d{8}\z/ },
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
|
10
|
+
def validate_each record, attribute, value
|
11
|
+
key = (options[:country] || I18n.locale).downcase.to_sym
|
12
|
+
key = :gb if key == :uk # Since it's easy to get this wrong
|
13
|
+
raise ArgumentError, "There is no validation for the country `#{key}'" if REGEXP[key].nil?
|
14
|
+
|
15
|
+
value = value.to_s
|
16
|
+
|
17
|
+
valid = true
|
18
|
+
if REGEXP[key].respond_to? :call
|
19
|
+
valid = false unless REGEXP[key].call value
|
20
|
+
elsif value !=~ REGEXP[key]
|
21
|
+
valid = false
|
22
|
+
end
|
23
|
+
|
24
|
+
if !valid
|
25
|
+
record.errors.add attribute, (options[:message] || I18n.t('rails_validations.commerce_number.invalid'))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -8,6 +8,7 @@ class PostalCodeValidator < ActiveModel::EachValidator
|
|
8
8
|
def validate_each record, attribute, value
|
9
9
|
key = (options[:country] || I18n.locale).downcase.to_sym
|
10
10
|
key = :gb if key == :uk # Since it's easy to get this wrong
|
11
|
+
raise ArgumentError, "There is no validation for the country `#{key}'" if REGEXP[key].nil?
|
11
12
|
|
12
13
|
record.errors.add attribute, (options[:message] || I18n.t('rails_validations.postal_code.invalid')) unless value =~ REGEXP[key]
|
13
14
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# https://en.wikipedia.org/wiki/VAT_identification_number
|
2
|
+
# http://ec.europa.eu/taxation_customs/vies/faqvies.do#item_7
|
3
|
+
class VatNumberValidator < ActiveModel::EachValidator
|
4
|
+
# keys are ISO-3366-1 alpha2
|
5
|
+
REGEXP = {
|
6
|
+
# 'NL' + 9 digits + B + 2-digit company index – e.g. NL999999999B99
|
7
|
+
# Allow space, -, and . for formatting
|
8
|
+
# TODO: I think this also has a check digit?
|
9
|
+
nl: -> (v) { v.upcase.gsub(/[.\- ]/, '') =~ /\ANL\d{9}B\d{2}\z/ },
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
|
13
|
+
def validate_each record, attribute, value
|
14
|
+
key = (options[:country] || I18n.locale).downcase.to_sym
|
15
|
+
key = :gb if key == :uk # Since it's easy to get this wrong
|
16
|
+
raise ArgumentError, "There is no validation for the country `#{key}'" if REGEXP[key].nil?
|
17
|
+
|
18
|
+
value = value.to_s
|
19
|
+
|
20
|
+
valid = true
|
21
|
+
if REGEXP[key].respond_to? :call
|
22
|
+
valid = false unless REGEXP[key].call value
|
23
|
+
elsif value !=~ REGEXP[key]
|
24
|
+
valid = false
|
25
|
+
end
|
26
|
+
|
27
|
+
if !valid
|
28
|
+
record.errors.add attribute, (options[:message] || I18n.t('rails_validations.vat_number.invalid'))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -82,10 +82,19 @@ end
|
|
82
82
|
|
83
83
|
shared_examples :validation do |validation|
|
84
84
|
it 'accepts a custom error message' do
|
85
|
-
with_validation "#{validation}: { message: 'foobar' }" do
|
85
|
+
with_validation "#{validation}: { country: :nl, message: 'foobar' }" do
|
86
86
|
m = described_class.new v: 'not even remotely valid'
|
87
87
|
expect(m.valid?).to eq(false)
|
88
88
|
expect(m.errors[:v].first).to eq('foobar')
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
|
94
|
+
shared_examples :country_code do |validation|
|
95
|
+
it 'raises an error on an invalid country' do
|
96
|
+
with_validation "#{validation}: { country: :not_a_country_code }" do
|
97
|
+
expect { described_class.new(v: 123).valid? }.to raise_error(ArgumentError)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ValidationsSpecHelper
|
4
|
+
class CommerceNumber < ValidationsSpecHelper::Record
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ValidationsSpecHelper::CommerceNumber do
|
9
|
+
include ValidationsSpecHelper
|
10
|
+
|
11
|
+
it_behaves_like :validation, 'commerce_number'
|
12
|
+
it_behaves_like :country_code, 'commerce_number'
|
13
|
+
|
14
|
+
it 'works for nl codes' do
|
15
|
+
with_validation 'commerce_number: { country: :nl }' do
|
16
|
+
[
|
17
|
+
12345678,
|
18
|
+
'12345678',
|
19
|
+
:'12345678',
|
20
|
+
'123 45-6.78',
|
21
|
+
].each do |v|
|
22
|
+
expect(model(v)).to be_valid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
it 'gives an error for nl codes' do
|
29
|
+
with_validation 'commerce_number: { country: :nl }' do
|
30
|
+
%w{
|
31
|
+
whoops
|
32
|
+
1234567
|
33
|
+
123456789
|
34
|
+
}.each do |v|
|
35
|
+
expect(model(v)).to be_invalid('commerce_number.invalid')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -10,6 +10,7 @@ describe ValidationsSpecHelper::PostalCode do
|
|
10
10
|
include ValidationsSpecHelper
|
11
11
|
|
12
12
|
it_behaves_like :validation, 'postal_code'
|
13
|
+
it_behaves_like :country_code, 'postal_code'
|
13
14
|
|
14
15
|
it 'works for nl codes' do
|
15
16
|
with_validation 'postal_code: { country: :nl }' do
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ValidationsSpecHelper
|
4
|
+
class VatNumber < ValidationsSpecHelper::Record
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ValidationsSpecHelper::VatNumber do
|
9
|
+
include ValidationsSpecHelper
|
10
|
+
|
11
|
+
it_behaves_like :validation, 'vat_number'
|
12
|
+
it_behaves_like :country_code, 'vat_number'
|
13
|
+
|
14
|
+
it 'works for nl codes' do
|
15
|
+
with_validation 'vat_number: { country: :nl }' do
|
16
|
+
%w{
|
17
|
+
NL123456789B00
|
18
|
+
NL123456789B99
|
19
|
+
NL.00-00\ 01\ 34-0B.57
|
20
|
+
nl123456789b00
|
21
|
+
}.each do |v|
|
22
|
+
expect(model(v)).to be_valid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
it 'gives an error for nl codes' do
|
29
|
+
with_validation 'vat_number: { country: :nl }' do
|
30
|
+
%w{
|
31
|
+
NL123456789A00
|
32
|
+
NL123456789B9
|
33
|
+
NL23456789B99
|
34
|
+
NL1234567890B99
|
35
|
+
NLL1234567890B99
|
36
|
+
}.each do |v|
|
37
|
+
expect(model(v)).to be_invalid('vat_number.invalid')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Tournoij
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -79,19 +79,24 @@ files:
|
|
79
79
|
- config/locales/en.yml
|
80
80
|
- config/locales/nl.yml
|
81
81
|
- lib/rails_validations.rb
|
82
|
+
- lib/validators/check_digit_validator.rb
|
83
|
+
- lib/validators/commerce_number_validator.rb
|
82
84
|
- lib/validators/date_validator.rb
|
83
85
|
- lib/validators/domain_validator.rb
|
84
86
|
- lib/validators/email_validator.rb
|
85
87
|
- lib/validators/iban_validator.rb
|
86
88
|
- lib/validators/phone_validator.rb
|
87
89
|
- lib/validators/postal_code_validator.rb
|
90
|
+
- lib/validators/vat_number_validator.rb
|
88
91
|
- spec/spec_helper.rb
|
92
|
+
- spec/validations/commerce_number_spec.rb
|
89
93
|
- spec/validations/date_spec.rb
|
90
94
|
- spec/validations/domain_spec.rb
|
91
95
|
- spec/validations/email_spec.rb
|
92
96
|
- spec/validations/iban_spec.rb
|
93
97
|
- spec/validations/phone_spec.rb
|
94
98
|
- spec/validations/postal_code_spec.rb
|
99
|
+
- spec/validations/vat_number_spec.rb
|
95
100
|
homepage: https://github.com/bluerail/rails_validations
|
96
101
|
licenses:
|
97
102
|
- MIT
|
@@ -124,3 +129,5 @@ test_files:
|
|
124
129
|
- spec/validations/phone_spec.rb
|
125
130
|
- spec/validations/postal_code_spec.rb
|
126
131
|
- spec/validations/domain_spec.rb
|
132
|
+
- spec/validations/commerce_number_spec.rb
|
133
|
+
- spec/validations/vat_number_spec.rb
|