validation_kit 1.0.5 → 2.0.1
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/CHANGELOG.md +150 -0
- data/LICENSE +21 -0
- data/README.md +200 -0
- data/lib/validation_kit/country_option.rb +35 -0
- data/lib/validation_kit/email_validator/email_validator.rb +26 -13
- data/lib/validation_kit/mixed_case_validator/config/locales/en.yml +4 -5
- data/lib/validation_kit/mixed_case_validator/config/locales/fr.yml +4 -5
- data/lib/validation_kit/mixed_case_validator/mixed_case_validator.rb +29 -28
- data/lib/validation_kit/phone_validator/phone_validator.rb +102 -80
- data/lib/validation_kit/postal_code_validator/postal_code_validator.rb +46 -47
- data/lib/validation_kit/version.rb +3 -1
- data/lib/validation_kit.rb +31 -6
- metadata +31 -20
- data/.gitignore +0 -4
- data/Gemfile +0 -4
- data/Rakefile +0 -1
- data/lib/validation_kit/email_validator/README +0 -32
- data/lib/validation_kit/mixed_case_validator/README +0 -59
- data/lib/validation_kit/phone_validator/README +0 -69
- data/lib/validation_kit/postal_code_validator/README +0 -44
- data/validation_kit.gemspec +0 -21
|
@@ -1,123 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ValidationKit
|
|
2
4
|
class PhoneValidator < ActiveModel::EachValidator
|
|
5
|
+
include CountryOption
|
|
6
|
+
|
|
7
|
+
# Digits right after a US/CA number with no marker in front of them (any
|
|
8
|
+
# letter, as in x, ext or extension, or #, # or №): a mistyped number like
|
|
9
|
+
# 212-555-12345, not an extension. \p{Nd} also catches non-ASCII digits.
|
|
10
|
+
UNMARKED_US_CA_EXTENSION = /\A[^[:alpha:]##№]*\p{Nd}/
|
|
11
|
+
|
|
12
|
+
# Australian states and territories (the area_key: values), and the
|
|
13
|
+
# landline area code each one adds.
|
|
14
|
+
AU_AREA_CODES = {
|
|
15
|
+
"NSW" => "02", "ACT" => "02", "VIC" => "03", "TAS" => "03",
|
|
16
|
+
"QLD" => "07", "SA" => "08", "NT" => "08", "WA" => "08"
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
# area_key: is a fixed state, so a typo fails when the model is loaded
|
|
20
|
+
# rather than silently adding the wrong area code.
|
|
21
|
+
def check_validity!
|
|
22
|
+
area_code_for_key(options[:area_key])
|
|
23
|
+
end
|
|
24
|
+
|
|
3
25
|
def regex_for_country(country_code)
|
|
26
|
+
country_code = country_code.to_s.strip.upcase
|
|
27
|
+
|
|
4
28
|
if country_code.blank?
|
|
5
29
|
nil
|
|
6
|
-
elsif
|
|
7
|
-
|
|
8
|
-
elsif [
|
|
9
|
-
|
|
10
|
-
else
|
|
11
|
-
nil
|
|
30
|
+
elsif country_code == "AU"
|
|
31
|
+
/\A(?:(?:1300|1800|1900|1902)\d{6}|(?:0?[12378])?[1-9][0-9]{7}|13\d{4}|0?4\d{8})\z/
|
|
32
|
+
elsif %w[US CA].include?(country_code)
|
|
33
|
+
/\A1?[2-9]\d{2}[2-9]\d{2}\d{4}/
|
|
12
34
|
end
|
|
13
35
|
end
|
|
14
36
|
|
|
15
37
|
def validate_each(record, attribute, value)
|
|
16
|
-
|
|
17
|
-
country = options[:country]
|
|
18
|
-
elsif options[:country].is_a?(Symbol) && record.respond_to?(options[:country])
|
|
19
|
-
country = record.send(options[:country])
|
|
20
|
-
elsif record.respond_to?(:country)
|
|
21
|
-
country = record.send(:country)
|
|
22
|
-
else
|
|
23
|
-
country = false
|
|
24
|
-
end
|
|
25
|
-
|
|
38
|
+
country = country_for(record)
|
|
26
39
|
return unless country
|
|
40
|
+
|
|
41
|
+
# accept "us", :US, " US " as well as "US"
|
|
42
|
+
country = country.to_s.strip.upcase
|
|
43
|
+
return if country.empty?
|
|
44
|
+
|
|
27
45
|
current_regex = regex_for_country(country)
|
|
28
46
|
return unless current_regex
|
|
29
47
|
|
|
30
|
-
new_value = value.to_s.gsub(/[^0-9]/,
|
|
31
|
-
new_value ||= ''
|
|
32
|
-
|
|
33
|
-
model_name = record.class.to_s
|
|
48
|
+
new_value = value.to_s.gsub(/[^0-9]/, "")
|
|
34
49
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
# allow_blank/allow_nil are handled by ActiveModel on the original value,
|
|
51
|
+
# so input that only becomes blank once cleaned up (e.g. "n/a") is invalid.
|
|
52
|
+
valid = current_regex.match?(new_value)
|
|
53
|
+
# The US/CA regex only checks the start of the digits; format_as_phone is
|
|
54
|
+
# what rejects extra digits that aren't a marked extension.
|
|
55
|
+
valid &&= !format_as_phone(value, country).nil? if %w[US CA].include?(country)
|
|
38
56
|
|
|
39
|
-
|
|
40
|
-
record.errors.add(attribute, message)
|
|
41
|
-
else
|
|
57
|
+
if valid
|
|
42
58
|
if options[:set]
|
|
43
59
|
formatted_phone = format_as_phone(value, country, options[:area_key])
|
|
44
60
|
if formatted_phone.nil?
|
|
45
|
-
record.errors.add(attribute, message)
|
|
61
|
+
record.errors.add(attribute, :invalid, message: options[:message])
|
|
46
62
|
else
|
|
47
|
-
record.
|
|
63
|
+
record.public_send("#{attribute}=", formatted_phone)
|
|
48
64
|
end
|
|
49
|
-
end
|
|
50
|
-
|
|
65
|
+
end
|
|
66
|
+
else
|
|
67
|
+
record.errors.add(attribute, :invalid, message: options[:message])
|
|
68
|
+
end
|
|
51
69
|
end
|
|
52
70
|
|
|
53
71
|
def format_as_phone(arg, country_code = nil, area_key = nil)
|
|
54
|
-
|
|
72
|
+
# Checked first, so a bad key always raises, whatever number is passed.
|
|
73
|
+
area_code = area_code_for_key(area_key)
|
|
74
|
+
country_code = country_code.to_s.strip.upcase
|
|
75
|
+
return nil if arg.blank? || country_code.blank? || !regex_for_country(country_code)
|
|
55
76
|
|
|
56
|
-
|
|
77
|
+
arg = arg.to_s
|
|
78
|
+
number = arg.gsub(/[^0-9]/, "")
|
|
57
79
|
|
|
58
80
|
if country_code == "AU"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
number.insert(4, ' ').insert(8, ' ')
|
|
74
|
-
else
|
|
75
|
-
number
|
|
81
|
+
case number
|
|
82
|
+
when /\A(?:1300|1800|1900|1902)\d{6}\z/
|
|
83
|
+
number.insert(4, " ").insert(8, " ")
|
|
84
|
+
when /\A(?:0?[12378])?[1-9][0-9]{7}\z/
|
|
85
|
+
number.insert(0, area_code) if /\A[1-9][0-9]{7}\z/.match?(number)
|
|
86
|
+
number.insert(0, "0") if /\A[12378][1-9][0-9]{7}\z/.match?(number)
|
|
87
|
+
|
|
88
|
+
number.insert(0, "(").insert(3, ") ").insert(9, " ")
|
|
89
|
+
when /\A13\d{4}\z/
|
|
90
|
+
number.insert(2, " ").insert(5, " ")
|
|
91
|
+
when /\A0?4\d{8}\z/
|
|
92
|
+
number.insert(0, "0") if /\A4\d{8}\z/.match?(number)
|
|
93
|
+
|
|
94
|
+
number.insert(4, " ").insert(8, " ")
|
|
76
95
|
end
|
|
77
|
-
elsif [
|
|
78
|
-
digit_count = number.length
|
|
96
|
+
elsif %w[CA US].include?(country_code)
|
|
79
97
|
# if it's too short
|
|
80
|
-
if
|
|
81
|
-
return number
|
|
82
|
-
end
|
|
98
|
+
return nil if number.length < 10
|
|
83
99
|
|
|
84
|
-
# strip off
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
# strip off the leading 1 (country code); any digits beyond ten are an
|
|
101
|
+
# extension, unless they're unmarked (UNMARKED_US_CA_EXTENSION)
|
|
102
|
+
leading_one = number.length > 10 && number.start_with?("1")
|
|
103
|
+
number = number[1..] if leading_one
|
|
88
104
|
|
|
89
105
|
area_code = number[0..2]
|
|
90
106
|
exchange = number[3..5]
|
|
91
107
|
sln = number[6..9]
|
|
92
108
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
# everything after the last digit of the number
|
|
110
|
+
national = arg[/\A(?:\D*\d){#{leading_one ? 11 : 10}}/]
|
|
111
|
+
rest = arg[national.length..]
|
|
112
|
+
|
|
113
|
+
# if letters appear among the number's digits, the extension's digits
|
|
114
|
+
# were counted as part of the number (e.g. 519 444 000 ext 123), so
|
|
115
|
+
# return nil to error out
|
|
116
|
+
return nil if number.length > 10 && national.sub(/\A\D*/, "").match?(/[[:alpha:]]/)
|
|
117
|
+
|
|
118
|
+
# Text after the number with no digits in it (e.g. "(cell)") is dropped;
|
|
119
|
+
# with digits, it's the extension, if they're marked as one.
|
|
120
|
+
extension = nil
|
|
121
|
+
if rest.match?(/\p{Nd}/)
|
|
122
|
+
return nil if UNMARKED_US_CA_EXTENSION.match?(rest)
|
|
123
|
+
|
|
124
|
+
# [[:space:]] also covers non-breaking spaces, which strip doesn't
|
|
125
|
+
extension = " #{rest.strip.sub(/\A[[:space:],;]+/, "").sub(/[[:space:]]+\z/, "")}"
|
|
103
126
|
end
|
|
104
127
|
|
|
105
|
-
"(
|
|
128
|
+
"(#{area_code}) #{exchange}-#{sln}#{extension}"
|
|
106
129
|
end
|
|
107
130
|
end
|
|
108
131
|
|
|
132
|
+
# key is an AU state, in any case, as a string or symbol (always the state
|
|
133
|
+
# itself, never a method name); nil or blank means NSW/ACT. Anything else
|
|
134
|
+
# raises, rather than silently adding the NSW/ACT code (02) to, say, a
|
|
135
|
+
# Victorian number.
|
|
109
136
|
def area_code_for_key(key)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
when 'SA' then '08'
|
|
117
|
-
when 'NT' then '08'
|
|
118
|
-
when 'WA' then '08'
|
|
119
|
-
else
|
|
120
|
-
'02'
|
|
137
|
+
state = key.to_s.strip.upcase
|
|
138
|
+
return AU_AREA_CODES["NSW"] if state.empty?
|
|
139
|
+
|
|
140
|
+
AU_AREA_CODES.fetch(state) do
|
|
141
|
+
raise ArgumentError, "area_key: #{key.inspect} isn't an Australian state or territory " \
|
|
142
|
+
"(#{AU_AREA_CODES.keys.join(", ")})"
|
|
121
143
|
end
|
|
122
144
|
end
|
|
123
145
|
end
|
|
@@ -1,88 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ValidationKit
|
|
2
4
|
class PostalCodeValidator < ActiveModel::EachValidator
|
|
5
|
+
include CountryOption
|
|
6
|
+
|
|
3
7
|
def postal_code_regex_for_country(country_code)
|
|
8
|
+
country_code = country_code.to_s.strip.upcase
|
|
9
|
+
|
|
4
10
|
if country_code.blank?
|
|
5
11
|
nil
|
|
6
|
-
elsif [
|
|
7
|
-
/\d{4}/
|
|
8
|
-
elsif
|
|
9
|
-
/\d{5}(
|
|
10
|
-
elsif
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
elsif %w[AU NZ].include?(country_code)
|
|
13
|
+
/\A\d{4}\z/
|
|
14
|
+
elsif country_code == "US"
|
|
15
|
+
/\A\d{5}(?:-?\d{4})?\z/
|
|
16
|
+
elsif country_code == "CA"
|
|
17
|
+
/\A[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTWVXYZ] ?\d[ABCEGHJKLMNPRSTWVXYZ]\d\z/
|
|
18
|
+
elsif %w[UK GB].include?(country_code)
|
|
19
|
+
/\A(?:[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0AA)\z/
|
|
14
20
|
end
|
|
15
21
|
end
|
|
16
22
|
|
|
17
23
|
def disallowed_characters_for_country(country_code)
|
|
24
|
+
country_code = country_code.to_s.strip.upcase
|
|
25
|
+
|
|
18
26
|
if country_code.blank?
|
|
19
27
|
nil
|
|
20
|
-
elsif [
|
|
28
|
+
elsif %w[US AU NZ].include?(country_code)
|
|
21
29
|
/[^0-9]/
|
|
22
|
-
elsif [
|
|
30
|
+
elsif %w[CA UK GB].include?(country_code)
|
|
23
31
|
/[^0-9A-Z]/
|
|
24
|
-
else
|
|
25
|
-
nil
|
|
26
32
|
end
|
|
27
33
|
end
|
|
28
34
|
|
|
29
35
|
def validate_each(record, attribute, value)
|
|
30
|
-
|
|
31
|
-
country = options[:country]
|
|
32
|
-
elsif options[:country].is_a?(Symbol) and record.respond_to?(options[:country])
|
|
33
|
-
country = record.send(options[:country])
|
|
34
|
-
elsif record.respond_to?(:country)
|
|
35
|
-
country = record.send(:country)
|
|
36
|
-
else
|
|
37
|
-
country = false
|
|
38
|
-
end
|
|
39
|
-
|
|
36
|
+
country = country_for(record)
|
|
40
37
|
return unless country
|
|
38
|
+
|
|
39
|
+
# accept "us", :US, " US " as well as "US"
|
|
40
|
+
country = country.to_s.strip.upcase
|
|
41
|
+
return if country.empty?
|
|
42
|
+
|
|
41
43
|
current_regex = postal_code_regex_for_country(country)
|
|
42
44
|
return unless current_regex
|
|
43
|
-
disallowed_characters = disallowed_characters_for_country(country)
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
disallowed_characters = disallowed_characters_for_country(country)
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
new_value = value.to_s.upcase.gsub(disallowed_characters, "")
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
# allow_blank/allow_nil are handled by ActiveModel on the original value,
|
|
51
|
+
# so input that only becomes blank once cleaned up (e.g. "n/a") is invalid.
|
|
52
|
+
if current_regex.match?(new_value)
|
|
53
|
+
if options[:set]
|
|
54
|
+
record.public_send("#{attribute}=", format_as_postal_code(new_value, country, disallowed_characters))
|
|
55
|
+
end
|
|
55
56
|
else
|
|
56
|
-
record.
|
|
57
|
-
format_as_postal_code(new_value, country, disallowed_characters)
|
|
58
|
-
) if options[:set]
|
|
57
|
+
record.errors.add(attribute, :invalid, message: options[:message])
|
|
59
58
|
end
|
|
60
59
|
end
|
|
61
60
|
|
|
62
61
|
def format_as_postal_code(arg, country_code, disallowed_characters)
|
|
63
|
-
|
|
62
|
+
country_code = country_code.to_s.strip.upcase
|
|
63
|
+
return nil if arg.blank? || country_code.blank? || !postal_code_regex_for_country(country_code)
|
|
64
64
|
|
|
65
|
-
postal_code = arg.gsub(disallowed_characters,
|
|
65
|
+
postal_code = arg.to_s.gsub(disallowed_characters, "")
|
|
66
66
|
|
|
67
|
-
if
|
|
67
|
+
if country_code == "US"
|
|
68
68
|
digit_count = postal_code.length
|
|
69
69
|
if digit_count == 5
|
|
70
|
-
|
|
70
|
+
postal_code
|
|
71
71
|
elsif digit_count == 9
|
|
72
|
-
|
|
73
|
-
else
|
|
74
|
-
return nil
|
|
72
|
+
"#{postal_code[0..4]}-#{postal_code[5..8]}"
|
|
75
73
|
end
|
|
76
74
|
|
|
77
|
-
elsif [
|
|
75
|
+
elsif %w[AU NZ].include?(country_code)
|
|
78
76
|
postal_code
|
|
79
77
|
|
|
80
|
-
elsif
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
elsif country_code == "CA"
|
|
79
|
+
# forward sortation area, then local delivery unit
|
|
80
|
+
"#{postal_code[0..2]} #{postal_code[3..5]}"
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
elsif %w[UK GB].include?(country_code)
|
|
83
|
+
# the inward code is always the last three characters
|
|
84
|
+
"#{postal_code[0...-3]} #{postal_code[-3..]}"
|
|
86
85
|
end
|
|
87
86
|
end
|
|
88
87
|
end
|
data/lib/validation_kit.rb
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_model"
|
|
4
|
+
require "active_support/core_ext/string/inflections"
|
|
1
5
|
require "validation_kit/version"
|
|
6
|
+
require "validation_kit/country_option"
|
|
7
|
+
|
|
8
|
+
module ValidationKit
|
|
9
|
+
VALIDATORS = {} # rubocop:disable Style/MutableConstant -- filled below, then frozen
|
|
10
|
+
|
|
11
|
+
# Lets `validates :email, email: true` (and phone:, postal_code:,
|
|
12
|
+
# mixed_case:) find this gem's validators. Rails resolves those keys with
|
|
13
|
+
# const_get on the model, and Ruby only calls const_missing once normal
|
|
14
|
+
# lookup -- including autoloading an app's own app/validators/*.rb -- has
|
|
15
|
+
# failed, so an app's validator of the same name always wins.
|
|
16
|
+
module ValidatorLookup
|
|
17
|
+
def const_missing(name)
|
|
18
|
+
VALIDATORS.fetch(name) { super }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
2
22
|
|
|
3
23
|
lib_path = File.dirname(__FILE__)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
validator = "ValidationKit::#{validator_class}".constantize
|
|
9
|
-
ActiveModel::Validations.const_set(validator_class, validator)
|
|
24
|
+
Dir[File.join(lib_path, "**", "*_validator.rb")].each do |path|
|
|
25
|
+
require path
|
|
26
|
+
name = File.basename(path, ".rb").camelize
|
|
27
|
+
ValidationKit::VALIDATORS[name.to_sym] = ValidationKit.const_get(name)
|
|
10
28
|
end
|
|
29
|
+
ValidationKit::VALIDATORS.freeze
|
|
30
|
+
|
|
31
|
+
ActiveModel::Validations::ClassMethods.include(ValidationKit::ValidatorLookup)
|
|
32
|
+
|
|
33
|
+
# Put the bundled translations first in the load path so an app's own
|
|
34
|
+
# locale files (which Rails appends later) can override them.
|
|
35
|
+
I18n.load_path.unshift(*Dir[File.join(lib_path, "validation_kit", "**", "locales", "*.yml")])
|
metadata
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: validation_kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wes Morgan
|
|
8
8
|
- Paul Schreiber
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
13
|
-
dependencies:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activemodel
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '7.2'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '7.2'
|
|
14
27
|
description: A collection of various validators for Rails forms
|
|
15
28
|
email:
|
|
16
29
|
- wes@turbovote.org
|
|
@@ -19,26 +32,26 @@ executables: []
|
|
|
19
32
|
extensions: []
|
|
20
33
|
extra_rdoc_files: []
|
|
21
34
|
files:
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
35
|
+
- CHANGELOG.md
|
|
36
|
+
- LICENSE
|
|
37
|
+
- README.md
|
|
25
38
|
- lib/validation_kit.rb
|
|
26
|
-
- lib/validation_kit/
|
|
39
|
+
- lib/validation_kit/country_option.rb
|
|
27
40
|
- lib/validation_kit/email_validator/email_validator.rb
|
|
28
|
-
- lib/validation_kit/mixed_case_validator/README
|
|
29
41
|
- lib/validation_kit/mixed_case_validator/config/locales/en.yml
|
|
30
42
|
- lib/validation_kit/mixed_case_validator/config/locales/fr.yml
|
|
31
43
|
- lib/validation_kit/mixed_case_validator/mixed_case_validator.rb
|
|
32
|
-
- lib/validation_kit/phone_validator/README
|
|
33
44
|
- lib/validation_kit/phone_validator/phone_validator.rb
|
|
34
|
-
- lib/validation_kit/postal_code_validator/README
|
|
35
45
|
- lib/validation_kit/postal_code_validator/postal_code_validator.rb
|
|
36
46
|
- lib/validation_kit/version.rb
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
metadata:
|
|
41
|
-
|
|
47
|
+
homepage: https://github.com/paulschreiber/validation_kit
|
|
48
|
+
licenses:
|
|
49
|
+
- MIT
|
|
50
|
+
metadata:
|
|
51
|
+
rubygems_mfa_required: 'true'
|
|
52
|
+
source_code_uri: https://github.com/paulschreiber/validation_kit
|
|
53
|
+
bug_tracker_uri: https://github.com/paulschreiber/validation_kit/issues
|
|
54
|
+
changelog_uri: https://github.com/paulschreiber/validation_kit/blob/main/CHANGELOG.md
|
|
42
55
|
rdoc_options: []
|
|
43
56
|
require_paths:
|
|
44
57
|
- lib
|
|
@@ -46,16 +59,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
46
59
|
requirements:
|
|
47
60
|
- - ">="
|
|
48
61
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: '
|
|
62
|
+
version: '3.4'
|
|
50
63
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
64
|
requirements:
|
|
52
65
|
- - ">="
|
|
53
66
|
- !ruby/object:Gem::Version
|
|
54
67
|
version: '0'
|
|
55
68
|
requirements: []
|
|
56
|
-
|
|
57
|
-
rubygems_version: 2.7.3
|
|
58
|
-
signing_key:
|
|
69
|
+
rubygems_version: 4.0.10
|
|
59
70
|
specification_version: 4
|
|
60
71
|
summary: Handy validations for Rails forms
|
|
61
72
|
test_files: []
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require "bundler/gem_tasks"
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
validates_as_email
|
|
2
|
-
==================
|
|
3
|
-
|
|
4
|
-
Validation module for email addresses.
|
|
5
|
-
|
|
6
|
-
Installation
|
|
7
|
-
============
|
|
8
|
-
|
|
9
|
-
You can install the plugin the traditional way. Go to your application root
|
|
10
|
-
and do:
|
|
11
|
-
|
|
12
|
-
script/plugin install git://github.com/paulschreiber/validates_as_email.git
|
|
13
|
-
|
|
14
|
-
Example
|
|
15
|
-
=======
|
|
16
|
-
|
|
17
|
-
class Person < ActiveRecord::Base
|
|
18
|
-
validates_as_email :email
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
p = Person.new(:email => "Bob")
|
|
22
|
-
p.valid? # false
|
|
23
|
-
|
|
24
|
-
p = Person.new(:email => "joe@foobar.com")
|
|
25
|
-
p.valid? # true
|
|
26
|
-
|
|
27
|
-
Just like with built-in ActiveRecord validations, you can optionally supply a :message parameter with a custom error. Or, you can use Rails' built-in localization system and
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
= License
|
|
31
|
-
|
|
32
|
-
Copyright (c) 2010 Paul Schreiber, released under the MIT license
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
Validates Mixed Case Of
|
|
2
|
-
=======================
|
|
3
|
-
|
|
4
|
-
When validating a string item, ensure it is not all in capital or lowercase letters.
|
|
5
|
-
|
|
6
|
-
Example
|
|
7
|
-
=======
|
|
8
|
-
|
|
9
|
-
class Person < ActiveRecord::Base
|
|
10
|
-
validates_mixed_case_of :firstname
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
p = Person.new(:firstname => "BOB")
|
|
14
|
-
p.valid? # false
|
|
15
|
-
p = Person.new(:firstname => "Bob")
|
|
16
|
-
p.valid? # true
|
|
17
|
-
|
|
18
|
-
Attribute Names
|
|
19
|
-
===============
|
|
20
|
-
Attribute names are looked up using Rails' I18n system. Create a hierarchy like so:
|
|
21
|
-
|
|
22
|
-
en:
|
|
23
|
-
activerecord:
|
|
24
|
-
models:
|
|
25
|
-
attributes:
|
|
26
|
-
person:
|
|
27
|
-
firstname: "first name"
|
|
28
|
-
|
|
29
|
-
Alternately, pass in the :attribute_name option:
|
|
30
|
-
|
|
31
|
-
class Person < ActiveRecord::Base
|
|
32
|
-
validates_mixed_case_of :firstname, :attribute_name => "first name"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Error Messages
|
|
37
|
-
==============
|
|
38
|
-
Error messages follow the standard ActiveRecord lookup method.
|
|
39
|
-
|
|
40
|
-
You'll likely error messages can be customized like so:
|
|
41
|
-
|
|
42
|
-
en:
|
|
43
|
-
activerecord:
|
|
44
|
-
errors:
|
|
45
|
-
models:
|
|
46
|
-
attributes:
|
|
47
|
-
person:
|
|
48
|
-
firstname:
|
|
49
|
-
all_caps: "first name should not be in all caps"
|
|
50
|
-
|
|
51
|
-
Alternatively, pass in tje :all_caps option:
|
|
52
|
-
|
|
53
|
-
class Person < ActiveRecord::Base
|
|
54
|
-
validates_mixed_case_of :firstname, :all_caps => "don't shout at me, bro"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Copyright 2011 Paul Schreiber, released under the MIT license
|