can_has_validations 0.6.2 → 1.1.0
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.md +50 -4
- data/lib/can_has_validations.rb +1 -1
- data/lib/can_has_validations/locale/en.yml +3 -1
- data/lib/can_has_validations/validators/email_validator.rb +42 -2
- data/lib/can_has_validations/validators/grandparent_validator.rb +2 -1
- data/lib/can_has_validations/validators/hostname_validator.rb +9 -4
- data/lib/can_has_validations/validators/ipaddr_validator.rb +91 -0
- data/lib/can_has_validations/validators/url_validator.rb +8 -2
- data/lib/can_has_validations/version.rb +1 -1
- metadata +30 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4b8c22fcbf2964d57091e6b566e5d05a1b501f286722ae26e4c63be5d42989f9
|
|
4
|
+
data.tar.gz: c2cdd19af9fa8459007d506f93e4dec5b1311c173d4fdf087c7438a1d387d97f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 115570baed1e6a8061612de3f6428599ab4b76afab032756db8a7df5d5aa8bf8ec76f91d52849b5a28b154349965028c5f295350e4fd8f62d86b7f298e046cf2
|
|
7
|
+
data.tar.gz: fa601d54efefa5ee3d83299b9838ba6684450009ef3f782e3904de6405ea6ecd05869e79e89daadf42904f8cfe8c791a2f397a1fb24ec08cd9ff1ced1bd269a9
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -10,6 +10,7 @@ Validations provided:
|
|
|
10
10
|
* Existence
|
|
11
11
|
* Grandparent
|
|
12
12
|
* Hostname
|
|
13
|
+
* IP address
|
|
13
14
|
* Ordering
|
|
14
15
|
* URL
|
|
15
16
|
* Write Once
|
|
@@ -147,14 +148,48 @@ TLD, so as to not fail as ICANN continues to add TLDs.
|
|
|
147
148
|
# allows '_abc.example.com'
|
|
148
149
|
validates :domain, hostname: {allow_underscore: true}
|
|
149
150
|
|
|
151
|
+
# allows '4.0/25.3.2.1.example.com'
|
|
152
|
+
validates :domain, hostname: {allow_slash: true}
|
|
153
|
+
|
|
150
154
|
# allows 'a.example.com', but not 'example.com'
|
|
151
155
|
validates :domain, hostname: {segments: 3..100}
|
|
152
156
|
|
|
157
|
+
# allows 'subdomain'
|
|
158
|
+
validates :subdomain, hostname: {segments: 1, skip_tld: true}
|
|
159
|
+
|
|
153
160
|
# allows '1.2.3.4' or 'a.example.com'
|
|
154
161
|
validates :domain, hostname: {allow_ip: true}
|
|
155
162
|
# use 4 or 6 for ipv4 or ipv6 only
|
|
156
163
|
|
|
157
164
|
|
|
165
|
+
## IP address validator ##
|
|
166
|
+
|
|
167
|
+
Ensures an attribute is generally formatted as a IP or IP block.
|
|
168
|
+
|
|
169
|
+
# allows '1.2.3.4' or '::1'
|
|
170
|
+
validates :ip, ipaddr: true
|
|
171
|
+
|
|
172
|
+
# allows '1.2.3.0/24' or '2001:db8::/64'
|
|
173
|
+
validates :cidr, ipaddr: {allow_block: true}
|
|
174
|
+
|
|
175
|
+
# if an ip block, the attribute must be fully contained within an allowed block.
|
|
176
|
+
# allows '10.0.0.1' and '10.0.0.0/24', but not '10.0.0.0/15'
|
|
177
|
+
validates :private_ip, ipaddr: {
|
|
178
|
+
allow_block: true,
|
|
179
|
+
within: [IPAddr.new('10.0.0.0/16'), '127.0.0.1']
|
|
180
|
+
# allowed IPs and blocks may be IPAddrs or Strings
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
# the inverse of :within
|
|
184
|
+
validates :public_ip6, ipaddr: {without: ['fc00::/7']]}
|
|
185
|
+
|
|
186
|
+
# :within and :without may also be procs or method names
|
|
187
|
+
validates :ip, ipaddr: {
|
|
188
|
+
within: :some_method,
|
|
189
|
+
without: ->(record){ ... }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
158
193
|
## Ordering validators ##
|
|
159
194
|
|
|
160
195
|
Ensures two attribute values maintain a relative order to one another. This is
|
|
@@ -180,13 +215,17 @@ Always skips over nil values; use `:presence` to validate those.
|
|
|
180
215
|
|
|
181
216
|
## URL validator ##
|
|
182
217
|
|
|
183
|
-
|
|
218
|
+
Ensures an attribute is generally formatted as a URL. If `addressable/uri` is
|
|
184
219
|
already loaded, it will be used to parse IDN's. Additionally, allowed schemes
|
|
185
220
|
can be specified; they default to ['http','https'].
|
|
186
221
|
|
|
187
222
|
validates :website, url: true
|
|
188
223
|
validates :secure_url, url: {scheme: 'https'}
|
|
189
224
|
|
|
225
|
+
# Dynamic list of schemes. *Must* return an array.
|
|
226
|
+
validates :git, url: {scheme: :some_method}
|
|
227
|
+
validates :old_school, url: {scheme: ->(record){ %w(ftp gopher) }}
|
|
228
|
+
|
|
190
229
|
# With IDN parsing:
|
|
191
230
|
require 'addressable/uri'
|
|
192
231
|
validates :website, url: true
|
|
@@ -198,8 +237,8 @@ can be specified; they default to ['http','https'].
|
|
|
198
237
|
|
|
199
238
|
## Write Once validator ##
|
|
200
239
|
|
|
201
|
-
|
|
202
|
-
for this.
|
|
240
|
+
Ensures that once a value is written, it becomes readonly. There are a few
|
|
241
|
+
uses for this.
|
|
203
242
|
|
|
204
243
|
The first is as an equivalent to `attr_readonly :user_id` except that it also
|
|
205
244
|
produces a validation error instead of silently ignoring the change as
|
|
@@ -214,6 +253,10 @@ sorts.
|
|
|
214
253
|
|
|
215
254
|
validates :user_id, allow_nil: true, write_once: true
|
|
216
255
|
|
|
256
|
+
The third use is to allow a nil value, and treat the nil also as write-once.
|
|
257
|
+
|
|
258
|
+
validates :source, write_once: {immutable_nil: true}
|
|
259
|
+
|
|
217
260
|
|
|
218
261
|
## Error messages
|
|
219
262
|
|
|
@@ -225,6 +268,9 @@ Default messages are as follows:
|
|
|
225
268
|
messages:
|
|
226
269
|
invalid_email: "is an invalid email"
|
|
227
270
|
invalid_hostname: "is an invalid hostname"
|
|
271
|
+
invalid_ip: "is an invalid IP"
|
|
272
|
+
ip_not_allowed: "is not an allowed IP"
|
|
273
|
+
single_ip_required: "must be a single IP"
|
|
228
274
|
invalid_url: "is an invalid URL"
|
|
229
275
|
unchangeable: "cannot be changed"
|
|
230
276
|
before: "must be before %{attribute2}"
|
|
@@ -233,4 +279,4 @@ Default messages are as follows:
|
|
|
233
279
|
|
|
234
280
|
## Compatibility ##
|
|
235
281
|
|
|
236
|
-
|
|
282
|
+
The current version is tested with Ruby 2.5-2.6 and ActiveModel 5.2-6.0.
|
data/lib/can_has_validations.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'active_model/validations'
|
|
2
2
|
|
|
3
|
-
%w(array email existence grandparent hostname ordering url write_once).each do |validator|
|
|
3
|
+
%w(array email existence grandparent hostname ipaddr ordering url write_once).each do |validator|
|
|
4
4
|
require "can_has_validations/validators/#{validator}_validator"
|
|
5
5
|
end
|
|
6
6
|
|
|
@@ -3,8 +3,10 @@ en:
|
|
|
3
3
|
messages:
|
|
4
4
|
invalid_email: "is an invalid email"
|
|
5
5
|
invalid_hostname: "is an invalid hostname"
|
|
6
|
+
invalid_ip: "is an invalid IP"
|
|
7
|
+
ip_not_allowed: "is not an allowed IP"
|
|
8
|
+
single_ip_required: "must be a single IP"
|
|
6
9
|
invalid_url: "is an invalid URL"
|
|
7
10
|
unchangeable: "cannot be changed"
|
|
8
11
|
before: "must be before %{attribute2}"
|
|
9
12
|
after: "must be after %{attribute2}"
|
|
10
|
-
|
|
@@ -1,15 +1,55 @@
|
|
|
1
1
|
# Ensure an attribute is generally formatted as an email.
|
|
2
2
|
# eg: validates :user_email, email: true
|
|
3
3
|
|
|
4
|
+
require_relative 'hostname_validator'
|
|
5
|
+
|
|
4
6
|
module ActiveModel::Validations
|
|
5
7
|
class EmailValidator < ActiveModel::EachValidator
|
|
6
8
|
|
|
7
|
-
EMAIL_REGEXP
|
|
9
|
+
EMAIL_REGEXP = /\A([a-z0-9._+-]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
|
10
|
+
SEGMENT_REGEXP = /\A[a-z0-9+_-]+\z/i
|
|
11
|
+
LABEL_REGEXP = HostnameValidator::LABEL_REGEXP
|
|
12
|
+
FINAL_LABEL_REGEXP = HostnameValidator::FINAL_LABEL_REGEXP
|
|
8
13
|
|
|
9
14
|
def validate_each(record, attribute, value)
|
|
10
|
-
unless value
|
|
15
|
+
unless email_valid?(value)
|
|
11
16
|
record.errors.add(attribute, :invalid_email, options.merge(value: value))
|
|
12
17
|
end
|
|
13
18
|
end
|
|
19
|
+
|
|
20
|
+
def email_valid?(value)
|
|
21
|
+
return unless value
|
|
22
|
+
recipient, domain = value.split('@', 2)
|
|
23
|
+
is_valid = true
|
|
24
|
+
|
|
25
|
+
recipient ||= ''
|
|
26
|
+
is_valid &&= recipient.length <= 255
|
|
27
|
+
is_valid &&= recipient !~ /\.\./
|
|
28
|
+
is_valid &&= !recipient.starts_with?('.')
|
|
29
|
+
is_valid &&= !recipient.ends_with?('.')
|
|
30
|
+
recipient.split('.').each do |segment|
|
|
31
|
+
is_valid &&= segment =~ SEGMENT_REGEXP
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
domain ||= ''
|
|
35
|
+
if defined?(Addressable::IDNA)
|
|
36
|
+
domain &&= Addressable::IDNA.to_ascii(domain)
|
|
37
|
+
end
|
|
38
|
+
labels = domain.split('.')
|
|
39
|
+
is_valid &&= domain.length <= 255
|
|
40
|
+
is_valid &&= domain !~ /\.\./
|
|
41
|
+
is_valid &&= labels.size.in? 2..100
|
|
42
|
+
labels.each_with_index do |label, idx|
|
|
43
|
+
is_valid &&= label.length <= 63
|
|
44
|
+
if idx+1==labels.size
|
|
45
|
+
is_valid &&= label =~ FINAL_LABEL_REGEXP
|
|
46
|
+
else
|
|
47
|
+
is_valid &&= label =~ LABEL_REGEXP
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
is_valid
|
|
52
|
+
end
|
|
53
|
+
|
|
14
54
|
end
|
|
15
55
|
end
|
|
@@ -16,7 +16,8 @@ module ActiveModel::Validations
|
|
|
16
16
|
if cousin.nil?
|
|
17
17
|
options[:allow_nil]
|
|
18
18
|
else
|
|
19
|
-
association
|
|
19
|
+
association &&
|
|
20
|
+
association.send(options[:parent]) == cousin.send(options[:parent])
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
unless all_match
|
|
@@ -18,19 +18,23 @@
|
|
|
18
18
|
# allows '*.example.com'
|
|
19
19
|
# validates :domain, hostname: {allow_underscore: true}
|
|
20
20
|
# allows '_abc.example.com'
|
|
21
|
+
# validates :domain, hostname: {allow_slash: true}
|
|
22
|
+
# allows '4.0/25.3.2.1.example.com' # rfc2317
|
|
21
23
|
# validates :domain, hostname: {segments: 3..100}
|
|
22
24
|
# allows 'a.example.com', but not 'example.com'
|
|
23
25
|
# validates :domain, hostname: {allow_ip: true} # or 4 or 6 for ipv4 or ipv6 only
|
|
24
26
|
# allows '1.2.3.4' or 'a.example.com'
|
|
27
|
+
# validates :subdomain, hostname: {skip_tld: true, segments: 1}
|
|
28
|
+
# allows 'subdomain1'
|
|
25
29
|
|
|
26
30
|
require 'resolv'
|
|
27
31
|
|
|
28
32
|
module ActiveModel::Validations
|
|
29
33
|
class HostnameValidator < ActiveModel::EachValidator
|
|
30
34
|
|
|
31
|
-
LABEL_REGEXP =
|
|
32
|
-
FINAL_LABEL_REGEXP =
|
|
33
|
-
RESERVED_OPTIONS = %i(allow_ip allow_underscore allow_wildcard)
|
|
35
|
+
LABEL_REGEXP = %r{\A([a-zA-Z0-9_]([a-zA-Z0-9_/-]+)?)?[a-zA-Z0-9]\z}
|
|
36
|
+
FINAL_LABEL_REGEXP = %r{\A(xn--[a-zA-Z0-9]{2,}|[a-zA-Z]{2,})\z}
|
|
37
|
+
RESERVED_OPTIONS = %i(allow_ip allow_slash allow_underscore allow_wildcard)
|
|
34
38
|
|
|
35
39
|
def validate_each(record, attribute, value)
|
|
36
40
|
case options[:allow_ip]
|
|
@@ -53,10 +57,11 @@ module ActiveModel::Validations
|
|
|
53
57
|
is_valid &&= value.length <= 255
|
|
54
58
|
is_valid &&= value !~ /\.\./
|
|
55
59
|
is_valid &&= value !~ /_/ unless options[:allow_underscore]
|
|
60
|
+
is_valid &&= value !~ %r{/} unless options[:allow_slash]
|
|
56
61
|
is_valid &&= labels.size.in? segments
|
|
57
62
|
labels.each_with_index do |label, idx|
|
|
58
63
|
is_valid &&= label.length <= 63
|
|
59
|
-
if idx+1==labels.size
|
|
64
|
+
if !options[:skip_tld] && idx+1==labels.size
|
|
60
65
|
is_valid &&= label =~ FINAL_LABEL_REGEXP
|
|
61
66
|
elsif options[:allow_wildcard] && idx==0
|
|
62
67
|
is_valid &&= label=='*' || label =~ LABEL_REGEXP
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Ensure an attribute is generally formatted as a IP or IP block.
|
|
2
|
+
# eg: validates :ip, ipaddr: true
|
|
3
|
+
# validates :cidr, ipaddr: {allow_block: true}
|
|
4
|
+
# validates :private_ip, ipaddr: {within: [IPAddr.new('10.0.0.0/8'), '127.0.0.1']}
|
|
5
|
+
# ip must be within any one of the provided ips/blocks
|
|
6
|
+
# if ip is block, it must be fully contained within any one of the provided blocks
|
|
7
|
+
# validates :public_ip6, ipaddr: {without: ['fc00::/7']]}
|
|
8
|
+
# ip must be outside all of the provided ips/blocks
|
|
9
|
+
# if ip is block, it must be fully outside all of the provided blocks
|
|
10
|
+
|
|
11
|
+
require 'ipaddr'
|
|
12
|
+
|
|
13
|
+
module ActiveModel::Validations
|
|
14
|
+
class IpaddrValidator < ActiveModel::EachValidator
|
|
15
|
+
|
|
16
|
+
def initialize(options)
|
|
17
|
+
options[:within] = normalize_within options[:within], :within
|
|
18
|
+
options[:without] = normalize_within options[:without], :without
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def validate_each(record, attribute, value)
|
|
23
|
+
allowed_ips = resolve_array record, options[:within]
|
|
24
|
+
disallowed_ips = resolve_array record, options[:without]
|
|
25
|
+
|
|
26
|
+
ip = case value
|
|
27
|
+
when IPAddr
|
|
28
|
+
ip
|
|
29
|
+
when String
|
|
30
|
+
IPAddr.new(value) rescue nil
|
|
31
|
+
end
|
|
32
|
+
unless ip
|
|
33
|
+
record.errors.add(attribute, :invalid_ip, options.merge(value: value))
|
|
34
|
+
return
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if !options[:allow_block] && (ip.ipv4? && ip.prefix!=32 or ip.ipv6? && ip.prefix!=128)
|
|
38
|
+
record.errors.add(attribute, :single_ip_required, options.merge(value: value))
|
|
39
|
+
end
|
|
40
|
+
if allowed_ips && allowed_ips.none?{|blk| blk.include? ip}
|
|
41
|
+
record.errors.add(attribute, :ip_not_allowed, options.merge(value: value))
|
|
42
|
+
elsif disallowed_ips && disallowed_ips.any?{|blk| blk.include? ip}
|
|
43
|
+
record.errors.add(attribute, :ip_not_allowed, options.merge(value: value))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def normalize_within(val, key)
|
|
51
|
+
if val.nil? || val.respond_to?(:call) || val.is_a?(Symbol)
|
|
52
|
+
val
|
|
53
|
+
else
|
|
54
|
+
Array(val).flatten.map do |i|
|
|
55
|
+
case i
|
|
56
|
+
when IPAddr
|
|
57
|
+
i
|
|
58
|
+
when String
|
|
59
|
+
IPAddr.new i
|
|
60
|
+
else
|
|
61
|
+
raise "Unexpected value for #{key.inspect} : #{i}"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def resolve_array(record, val)
|
|
68
|
+
res = if val.respond_to?(:call)
|
|
69
|
+
val.call(record)
|
|
70
|
+
elsif val.is_a?(Symbol)
|
|
71
|
+
record.send(val)
|
|
72
|
+
else
|
|
73
|
+
val
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# tests for & fixes broken IPAddr <= 1.2.2
|
|
81
|
+
if IPAddr.new('192.168.2.0/32').include? '192.168.2.0/24'
|
|
82
|
+
# warn 'IPAddr <= 1.2.2 is broken; monkey-patching'
|
|
83
|
+
class IPAddr
|
|
84
|
+
def include?(other)
|
|
85
|
+
range = to_range
|
|
86
|
+
other = coerce_other(other).to_range
|
|
87
|
+
range.begin <= other.begin && range.end >= other.end
|
|
88
|
+
end
|
|
89
|
+
alias === include?
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -7,7 +7,13 @@
|
|
|
7
7
|
module ActiveModel::Validations
|
|
8
8
|
class UrlValidator < ActiveModel::EachValidator
|
|
9
9
|
def validate_each(record, attribute, value)
|
|
10
|
-
allowed_schemes =
|
|
10
|
+
allowed_schemes = if options[:scheme].respond_to?(:call)
|
|
11
|
+
options[:scheme].call(record)
|
|
12
|
+
elsif options[:scheme].is_a?(Symbol)
|
|
13
|
+
record.send(options[:scheme])
|
|
14
|
+
else
|
|
15
|
+
Array.wrap(options[:scheme] || %w(http https))
|
|
16
|
+
end
|
|
11
17
|
|
|
12
18
|
if defined?(Addressable::URI)
|
|
13
19
|
u = Addressable::URI.parse(value) rescue nil
|
|
@@ -16,7 +22,7 @@ module ActiveModel::Validations
|
|
|
16
22
|
u2 = u = URI.parse(value) rescue nil
|
|
17
23
|
end
|
|
18
24
|
if !u || !u2 || u.relative? || allowed_schemes.exclude?(u.scheme)
|
|
19
|
-
record.errors.add(attribute, :invalid_url, options.merge(value: value))
|
|
25
|
+
record.errors.add(attribute, :invalid_url, options.merge(value: value, scheme: allowed_schemes))
|
|
20
26
|
end
|
|
21
27
|
end
|
|
22
28
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: can_has_validations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thomas morgan
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-12-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -16,20 +16,20 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '5.0'
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '6'
|
|
22
|
+
version: '6.1'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
27
|
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
29
|
+
version: '5.0'
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '6'
|
|
32
|
+
version: '6.1'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: sqlite3
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -44,7 +44,7 @@ dependencies:
|
|
|
44
44
|
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
46
|
version: '0'
|
|
47
|
-
description: Assorted Rails
|
|
47
|
+
description: Assorted Rails 5.x-6.x validators.
|
|
48
48
|
email:
|
|
49
49
|
- tm@iprog.com
|
|
50
50
|
executables: []
|
|
@@ -61,6 +61,7 @@ files:
|
|
|
61
61
|
- lib/can_has_validations/validators/existence_validator.rb
|
|
62
62
|
- lib/can_has_validations/validators/grandparent_validator.rb
|
|
63
63
|
- lib/can_has_validations/validators/hostname_validator.rb
|
|
64
|
+
- lib/can_has_validations/validators/ipaddr_validator.rb
|
|
64
65
|
- lib/can_has_validations/validators/ordering_validator.rb
|
|
65
66
|
- lib/can_has_validations/validators/url_validator.rb
|
|
66
67
|
- lib/can_has_validations/validators/write_once_validator.rb
|
|
@@ -100,7 +101,7 @@ files:
|
|
|
100
101
|
homepage: https://github.com/zarqman/can_has_validations
|
|
101
102
|
licenses: []
|
|
102
103
|
metadata: {}
|
|
103
|
-
post_install_message:
|
|
104
|
+
post_install_message:
|
|
104
105
|
rdoc_options: []
|
|
105
106
|
require_paths:
|
|
106
107
|
- lib
|
|
@@ -115,40 +116,39 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
115
116
|
- !ruby/object:Gem::Version
|
|
116
117
|
version: '0'
|
|
117
118
|
requirements: []
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
signing_key:
|
|
119
|
+
rubygems_version: 3.0.8
|
|
120
|
+
signing_key:
|
|
121
121
|
specification_version: 4
|
|
122
|
-
summary: Assorted Rails
|
|
122
|
+
summary: Assorted Rails 5.x-6.x validators
|
|
123
123
|
test_files:
|
|
124
|
-
- test/
|
|
124
|
+
- test/dummy/app/controllers/application_controller.rb
|
|
125
|
+
- test/dummy/app/views/layouts/application.html.erb
|
|
125
126
|
- test/dummy/app/assets/javascripts/application.js
|
|
126
127
|
- test/dummy/app/assets/stylesheets/application.css
|
|
127
|
-
- test/dummy/app/controllers/application_controller.rb
|
|
128
128
|
- test/dummy/app/helpers/application_helper.rb
|
|
129
|
-
- test/dummy/
|
|
130
|
-
- test/dummy/config/
|
|
131
|
-
- test/dummy/config/boot.rb
|
|
132
|
-
- test/dummy/config/database.yml
|
|
133
|
-
- test/dummy/config/environment.rb
|
|
134
|
-
- test/dummy/config/environments/development.rb
|
|
129
|
+
- test/dummy/config/routes.rb
|
|
130
|
+
- test/dummy/config/locales/en.yml
|
|
135
131
|
- test/dummy/config/environments/production.rb
|
|
132
|
+
- test/dummy/config/environments/development.rb
|
|
136
133
|
- test/dummy/config/environments/test.rb
|
|
134
|
+
- test/dummy/config/environment.rb
|
|
135
|
+
- test/dummy/config/application.rb
|
|
136
|
+
- test/dummy/config/database.yml
|
|
137
|
+
- test/dummy/config/boot.rb
|
|
137
138
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
|
138
|
-
- test/dummy/config/initializers/inflections.rb
|
|
139
139
|
- test/dummy/config/initializers/mime_types.rb
|
|
140
|
-
- test/dummy/config/initializers/secret_token.rb
|
|
141
140
|
- test/dummy/config/initializers/session_store.rb
|
|
142
141
|
- test/dummy/config/initializers/wrap_parameters.rb
|
|
143
|
-
- test/dummy/config/
|
|
144
|
-
- test/dummy/config/
|
|
142
|
+
- test/dummy/config/initializers/secret_token.rb
|
|
143
|
+
- test/dummy/config/initializers/inflections.rb
|
|
145
144
|
- test/dummy/config.ru
|
|
146
|
-
- test/dummy/
|
|
147
|
-
- test/dummy/
|
|
145
|
+
- test/dummy/script/rails
|
|
146
|
+
- test/dummy/Rakefile
|
|
147
|
+
- test/dummy/public/favicon.ico
|
|
148
148
|
- test/dummy/public/422.html
|
|
149
149
|
- test/dummy/public/500.html
|
|
150
|
-
- test/dummy/public/
|
|
151
|
-
- test/dummy/
|
|
150
|
+
- test/dummy/public/404.html
|
|
151
|
+
- test/dummy/log/test.log
|
|
152
152
|
- test/dummy/README.rdoc
|
|
153
|
-
- test/
|
|
153
|
+
- test/can_has_validations_test.rb
|
|
154
154
|
- test/test_helper.rb
|