rails-alpha_numeric_validator 0.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.
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +30 -0
- data/Rakefile +1 -0
- data/bin/set_lc.sh +47 -0
- data/lib/rails/alpha_numeric_validator.rb +87 -0
- data/lib/rails/alpha_numeric_validator/version.rb +5 -0
- data/rails-alpha_numeric_validator.gemspec +53 -0
- data/test/alpha_numeric_validator_test.rb +64 -0
- metadata +159 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Paul Belt
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
rails-alpha_numeric_validator
|
2
|
+
=============================
|
3
|
+
|
4
|
+
validate model attributes follow specific guidelines e.g. only printable characters, no whitespace, etc
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'rails-alpha_numeric_validator'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install rails-alpha_numeric_validator
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
TODO: Write usage instructions here
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
|
26
|
+
1. Fork it
|
27
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
28
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
29
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
30
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/set_lc.sh
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Pick one EVENT or SWIFTIPLY
|
2
|
+
# To run a Rails app in evented mode (eventmachine gem)
|
3
|
+
export EVENT=1
|
4
|
+
|
5
|
+
# To run in swiftiplied mode (swiftiply gem)
|
6
|
+
#export SWIFTIPLY=1
|
7
|
+
|
8
|
+
# HACK: broken locales
|
9
|
+
my_hosttype="${HOSTTYPE:='unknown_hosttype'}"
|
10
|
+
my_kernel="${OSTYPE:='unknown_kernel'}"
|
11
|
+
my_hosttype=$(uname -a)
|
12
|
+
my_kernel=$(uname -s)
|
13
|
+
|
14
|
+
if [ "${my_kernel}" != 'Darwin' ]; then
|
15
|
+
my_kernel="${my_kernel/SunOS/solaris}"
|
16
|
+
fi
|
17
|
+
|
18
|
+
# TODO: re-write my_osver detection to include major-minor-patch
|
19
|
+
my_ostype="${my_kernel/Darwin*/darwin}"
|
20
|
+
my_osver="${my_kernel/darwin/}"
|
21
|
+
|
22
|
+
if [ "${my_ostype}" != 'darwin' ]; then
|
23
|
+
my_ostype="${my_kernel/Linux*/linux}"
|
24
|
+
if [ "${my_ostype}" != 'linux' ]; then
|
25
|
+
my_ostype="${my_kernel/-gnu/}"
|
26
|
+
fi
|
27
|
+
my_osver="${my_kernel/linux-/}"
|
28
|
+
if [ ${my_ostype} != 'linux' ]; then
|
29
|
+
my_ostype="${my_kernel/solaris*/solaris}"
|
30
|
+
my_osver="${my_kernel/solaris/}"
|
31
|
+
fi
|
32
|
+
fi
|
33
|
+
|
34
|
+
case "${my_ostype}" in
|
35
|
+
'darwin' )
|
36
|
+
LC_CTYPE='en_US.UTF-8'; builtin export LC_CTYPE
|
37
|
+
LC_ALL='en_US.UTF-8'; builtin export LC_ALL # Mnt. Lion
|
38
|
+
;;
|
39
|
+
'linux' )
|
40
|
+
LANG='en_US.UTF-8'; builtin export LANG
|
41
|
+
LC_ALL='en_US.UTF-8'; builtin export LC_ALL
|
42
|
+
;;
|
43
|
+
* )
|
44
|
+
echo "Unsupported OS: ${my_ostype}"
|
45
|
+
;;
|
46
|
+
esac
|
47
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# validate attributes have only alpha, numeric and whitespace
|
2
|
+
require 'rails/alpha_numeric_validator/version'
|
3
|
+
|
4
|
+
class AlphaNumericValidator < ActiveModel::EachValidator
|
5
|
+
attr_accessor :string # :nodoc:
|
6
|
+
|
7
|
+
PUNCTUATION_REGEXP = {
|
8
|
+
default: /(?:[[:alpha:]]|[[:digit:]])+/,
|
9
|
+
:true => /(?:[[:graph:]])+/,
|
10
|
+
limited: /(?:[[:alpha:]]|[[:digit:]]|[_\+\.\?,\-!'\/#])+/, # ' vim-color-syntax hack
|
11
|
+
dns: /(?:[[:alpha:]]|[[:digit:]]|-)+/,
|
12
|
+
fqdn: /(?:[[:alpha:]]|[[:digit:]]|-|\.)+/}
|
13
|
+
|
14
|
+
WHITESPACE_EXCEPTIONS = [:dns, :fqdn]
|
15
|
+
|
16
|
+
# == Creation
|
17
|
+
# To use the AlphaNumericValidator, initialize it as any other class
|
18
|
+
#
|
19
|
+
# class ExampleValidator < ActiveRecord::Base
|
20
|
+
# validates :attr1, alpha_numeric: true
|
21
|
+
# validates :attr2, alpha_numeric: {punctuation: true}
|
22
|
+
# validates :attr3, alpha_numeric: {punctuation: :limited}
|
23
|
+
# validates :attr4, alpha_numeric: {allow_nil: false, allow_blank: false}
|
24
|
+
# validates :attr4, alpha_numeric: {allow_whitespace: true}
|
25
|
+
# validates :attr4, alpha_numeric: {dns: true}
|
26
|
+
# end
|
27
|
+
|
28
|
+
def initialize(*args) # :nodoc:
|
29
|
+
@errors = []
|
30
|
+
@record = nil
|
31
|
+
super(*args)
|
32
|
+
end
|
33
|
+
|
34
|
+
# :call-seq:
|
35
|
+
# validate_each :record, :attribute, :value
|
36
|
+
#
|
37
|
+
# <tt>:record</tt>:: AR instance
|
38
|
+
# <tt>:attribute</tt>:: symbol for attribute
|
39
|
+
# <tt>:value</tt>:: value to check validity
|
40
|
+
|
41
|
+
def validate_each(record, attribute, value) #:nodoc:
|
42
|
+
@record = record
|
43
|
+
opts = {punctuation: :default}
|
44
|
+
opts.merge! allow_whitespace: !WHITESPACE_EXCEPTIONS.member?(@options[:punctuation])
|
45
|
+
@options = opts.merge @options
|
46
|
+
|
47
|
+
# TODO: document why value[1]
|
48
|
+
@string = value.is_a?(Array) ? value[1] : value
|
49
|
+
unless @string.nil? || @string.class.ancestors.include?(Numeric) || is_valid?
|
50
|
+
record.errors[attribute] << 'invalid characters'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# :call-seq:
|
55
|
+
# is_valid?
|
56
|
+
#
|
57
|
+
# alias for :is_valid_string?
|
58
|
+
|
59
|
+
def is_valid?
|
60
|
+
is_valid_string?
|
61
|
+
end
|
62
|
+
|
63
|
+
# :call-seq:
|
64
|
+
# is_valid_string?
|
65
|
+
#
|
66
|
+
# returns true if the string only contains the requested character set
|
67
|
+
#
|
68
|
+
# TODO: support international DNS
|
69
|
+
|
70
|
+
def is_valid_string?
|
71
|
+
return true if @options[:allow_nil] && !@string
|
72
|
+
return false if !@options[:allow_blank] && @string.blank?
|
73
|
+
return false if !@options[:allow_whitespace] && has_whitespace?
|
74
|
+
re = PUNCTUATION_REGEXP[@options[:punctuation].to_s.to_sym]
|
75
|
+
@string.to_s.gsub(re, "").blank?
|
76
|
+
end
|
77
|
+
|
78
|
+
# :call-seq:
|
79
|
+
# has_whitespace?
|
80
|
+
#
|
81
|
+
# returns true if the string contains whitespace
|
82
|
+
|
83
|
+
def has_whitespace?
|
84
|
+
@string.to_s.match /(?:\s)+/
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rails/alpha_numeric_validator/version'
|
5
|
+
|
6
|
+
REQUIREMENTS = {
|
7
|
+
runtime: {
|
8
|
+
rails: ['~> 3.2.13']},
|
9
|
+
development: {
|
10
|
+
bundler: ['~> 1.3'],
|
11
|
+
rake: ['>= 0'],
|
12
|
+
sqlite3: ['>= 1.3.7'],
|
13
|
+
debugger: ['>= 1.5.0'],
|
14
|
+
rspec: ['>= 2.13.0']}
|
15
|
+
}
|
16
|
+
|
17
|
+
Gem::Specification.new do |spec|
|
18
|
+
spec.name = 'rails-alpha_numeric_validator'
|
19
|
+
spec.version = Rails::AlphaNumericValidator::VERSION
|
20
|
+
spec.authors = ['Paul Belt']
|
21
|
+
spec.email = %w(saprb@channing.harvard.edu)
|
22
|
+
spec.description = %q{validate model attributes follow specific guidelines e.g. only printable characters, no whitespace, etc}
|
23
|
+
spec.summary = %q{validate model attributes follow specific guidelines e.g. only printable characters, no whitespace, etc}
|
24
|
+
spec.homepage = 'https://github.com/belt/rails-alpha_numeric_validator'
|
25
|
+
spec.license = 'MIT'
|
26
|
+
|
27
|
+
spec.files = `git ls-files`.split($/)
|
28
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |fn| File.basename(fn) }
|
29
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
30
|
+
spec.require_paths = %w(lib)
|
31
|
+
|
32
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 1.9.2')
|
33
|
+
spec.required_rubygems_version = Gem::Requirement.new('>= 0') if spec.respond_to? :required_rubygems_version=
|
34
|
+
|
35
|
+
[:runtime, :development].each do |mode|
|
36
|
+
REQUIREMENTS[mode].each do |req, ver|
|
37
|
+
if spec.respond_to? :specification_version
|
38
|
+
spec.specification_version = 3
|
39
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0')
|
40
|
+
if mode == :runtime
|
41
|
+
spec.add_runtime_dependency req.to_s, ver
|
42
|
+
else
|
43
|
+
spec.add_development_dependency req.to_s, ver
|
44
|
+
end
|
45
|
+
else
|
46
|
+
spec.add_dependency req.to_s, ver
|
47
|
+
end
|
48
|
+
else
|
49
|
+
spec.add_dependency req.to_s, ver
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rails'
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
if $LOAD_PATH.include?(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
6
|
+
require 'rails/alpha_numeric_validator'
|
7
|
+
else
|
8
|
+
raise RuntimeError, "Try ruby -Ilib test/#{File.basename(__FILE__)}"
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(:version => 1) do
|
14
|
+
create_table :models do |t|
|
15
|
+
t.string :name
|
16
|
+
t.string :organization
|
17
|
+
t.string :favorite_quote
|
18
|
+
t.string :server_name
|
19
|
+
t.string :website
|
20
|
+
t.string :id_code
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Model < ActiveRecord::Base
|
25
|
+
attr_accessible :name, :organization, :favorite_quote, :server_name, :website, :id_code
|
26
|
+
validates :name, :alpha_numeric => true
|
27
|
+
validates :organization, :alpha_numeric => {punctuation: :limited}
|
28
|
+
validates :favorite_quote, :alpha_numeric => {punctuation: true, allow_nil: true, allow_blank: true}
|
29
|
+
validates :server_name, :alpha_numeric => {punctuation: :dns}
|
30
|
+
validates :website, :alpha_numeric => {punctuation: :fqdn}
|
31
|
+
validates :id_code, :alpha_numeric => {allow_whitespace: false}
|
32
|
+
end
|
33
|
+
|
34
|
+
class AlphaNumericValidatorTest < Test::Unit::TestCase
|
35
|
+
def validate_field(record, field, valid_values, invalid_values)
|
36
|
+
original_value = record.send(field)
|
37
|
+
assignment_method = "#{field}=".to_sym
|
38
|
+
valid_values.each do |value|
|
39
|
+
record.send(assignment_method, value)
|
40
|
+
assert record.valid?
|
41
|
+
end
|
42
|
+
invalid_values.each do |value|
|
43
|
+
record.send(assignment_method, value)
|
44
|
+
assert !record.valid?
|
45
|
+
end
|
46
|
+
record.send(assignment_method, original_value)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_alpha_numeric_validation
|
50
|
+
@model = Model.new(:name => 'Paul Belt', :organization => 'Hello Corp.', :favorite_quote => 'Hello world!',
|
51
|
+
:server_name => 'hello-world', :website => 'hello-world.example.com', :id_code => 'abc123')
|
52
|
+
assert @model.valid?
|
53
|
+
validations = {name: [['Bob1 Jones2', 'abcdef'], ['Bob# Jones?', '!@#$!@']],
|
54
|
+
organization: [["McDonald's", 'Yahoo!', 'ABC-DEF + GHI'], %w(A@B XYZ~3)],
|
55
|
+
favorite_quote: [['This$is=a& good*string', '~!@#$%^&*()'], %W(Hello\x00)],
|
56
|
+
server_name: [%w(hello1 abcdef), ['hello world', 'hello~world']],
|
57
|
+
website: [%w(abc123.example.com example.com), ['he llo.example.com', 'my@site.com']],
|
58
|
+
id_code: [%w(hello1 abcdef), ['hello world', 'hello-world']]}
|
59
|
+
validations.each do |k, v|
|
60
|
+
validate_field(@model, k, v[0], v[1])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails-alpha_numeric_validator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Paul Belt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 3.2.13
|
21
|
+
none: false
|
22
|
+
requirement: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.2.13
|
27
|
+
none: false
|
28
|
+
prerelease: false
|
29
|
+
type: :runtime
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '1.3'
|
37
|
+
none: false
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '1.3'
|
43
|
+
none: false
|
44
|
+
prerelease: false
|
45
|
+
type: :development
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
none: false
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
none: false
|
60
|
+
prerelease: false
|
61
|
+
type: :development
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: sqlite3
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.3.7
|
69
|
+
none: false
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.3.7
|
75
|
+
none: false
|
76
|
+
prerelease: false
|
77
|
+
type: :development
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: debugger
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.5.0
|
85
|
+
none: false
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.5.0
|
91
|
+
none: false
|
92
|
+
prerelease: false
|
93
|
+
type: :development
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 2.13.0
|
101
|
+
none: false
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 2.13.0
|
107
|
+
none: false
|
108
|
+
prerelease: false
|
109
|
+
type: :development
|
110
|
+
description: validate model attributes follow specific guidelines e.g. only printable
|
111
|
+
characters, no whitespace, etc
|
112
|
+
email:
|
113
|
+
- saprb@channing.harvard.edu
|
114
|
+
executables:
|
115
|
+
- set_lc.sh
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- .gitignore
|
120
|
+
- .rspec
|
121
|
+
- .ruby-gemset
|
122
|
+
- .ruby-version
|
123
|
+
- Gemfile
|
124
|
+
- LICENSE.txt
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- bin/set_lc.sh
|
128
|
+
- lib/rails/alpha_numeric_validator.rb
|
129
|
+
- lib/rails/alpha_numeric_validator/version.rb
|
130
|
+
- rails-alpha_numeric_validator.gemspec
|
131
|
+
- test/alpha_numeric_validator_test.rb
|
132
|
+
homepage: https://github.com/belt/rails-alpha_numeric_validator
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options: []
|
137
|
+
require_paths:
|
138
|
+
- lib
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 1.9.2
|
144
|
+
none: false
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
none: false
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.8.25
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: validate model attributes follow specific guidelines e.g. only printable
|
157
|
+
characters, no whitespace, etc
|
158
|
+
test_files:
|
159
|
+
- test/alpha_numeric_validator_test.rb
|