whyvalidationssuckin96 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.md +121 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/doc/ActiveRecord/RecordInvalid.html +258 -0
- data/doc/ActiveRecord.html +93 -0
- data/doc/FalseClass.html +87 -0
- data/doc/NilClass.html +87 -0
- data/doc/Numeric.html +87 -0
- data/doc/Object.html +79 -0
- data/doc/String.html +87 -0
- data/doc/TrueClass.html +87 -0
- data/doc/WhyValidationsSuckIn96/ActiveRecord/InstanceMethods.html +156 -0
- data/doc/WhyValidationsSuckIn96/ActiveRecord.html +192 -0
- data/doc/WhyValidationsSuckIn96/AttributeBasedValidation.html +464 -0
- data/doc/WhyValidationsSuckIn96/SkippableValidation.html +194 -0
- data/doc/WhyValidationsSuckIn96/ValidatesAcceptance.html +254 -0
- data/doc/WhyValidationsSuckIn96/ValidatesAssociated.html +250 -0
- data/doc/WhyValidationsSuckIn96/ValidatesConfirmation.html +251 -0
- data/doc/WhyValidationsSuckIn96/ValidatesExclusion.html +388 -0
- data/doc/WhyValidationsSuckIn96/ValidatesFormat.html +387 -0
- data/doc/WhyValidationsSuckIn96/ValidatesInclusion.html +388 -0
- data/doc/WhyValidationsSuckIn96/ValidatesLength.html +469 -0
- data/doc/WhyValidationsSuckIn96/ValidatesNumericality.html +267 -0
- data/doc/WhyValidationsSuckIn96/ValidatesPresence.html +244 -0
- data/doc/WhyValidationsSuckIn96/ValidatesUniqueness.html +289 -0
- data/doc/WhyValidationsSuckIn96/Validation.html +934 -0
- data/doc/WhyValidationsSuckIn96/ValidationBuilder.html +391 -0
- data/doc/WhyValidationsSuckIn96/ValidationSupport/ClassMethods.html +249 -0
- data/doc/WhyValidationsSuckIn96/ValidationSupport/InstanceMethods.html +484 -0
- data/doc/WhyValidationsSuckIn96/ValidationSupport.html +168 -0
- data/doc/WhyValidationsSuckIn96.html +97 -0
- data/doc/_index.html +346 -0
- data/doc/class_list.html +293 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +23 -0
- data/doc/css/style.css +263 -0
- data/doc/file.README.html +173 -0
- data/doc/file_list.html +29 -0
- data/doc/index.html +173 -0
- data/doc/js/app.js +91 -0
- data/doc/js/full_list.js +39 -0
- data/doc/js/jquery.js +19 -0
- data/doc/method_list.html +462 -0
- data/doc/top-level-namespace.html +81 -0
- data/lib/whyvalidationssuckin96/attribute_based_validation.rb +46 -0
- data/lib/whyvalidationssuckin96/constants.rb +3 -0
- data/lib/whyvalidationssuckin96/ext/blank.rb +47 -0
- data/lib/whyvalidationssuckin96/macros/validates_acceptance.rb +36 -0
- data/lib/whyvalidationssuckin96/macros/validates_associated.rb +33 -0
- data/lib/whyvalidationssuckin96/macros/validates_confirmation.rb +40 -0
- data/lib/whyvalidationssuckin96/macros/validates_exclusion.rb +38 -0
- data/lib/whyvalidationssuckin96/macros/validates_format.rb +38 -0
- data/lib/whyvalidationssuckin96/macros/validates_inclusion.rb +38 -0
- data/lib/whyvalidationssuckin96/macros/validates_length.rb +98 -0
- data/lib/whyvalidationssuckin96/macros/validates_numericality.rb +56 -0
- data/lib/whyvalidationssuckin96/macros/validates_presence.rb +30 -0
- data/lib/whyvalidationssuckin96/macros.rb +9 -0
- data/lib/whyvalidationssuckin96/rails/active_record.rb +94 -0
- data/lib/whyvalidationssuckin96/rails/macros/validates_uniqueness.rb +87 -0
- data/lib/whyvalidationssuckin96/rails/macros.rb +1 -0
- data/lib/whyvalidationssuckin96/skippable_validation.rb +59 -0
- data/lib/whyvalidationssuckin96/validation.rb +88 -0
- data/lib/whyvalidationssuckin96/validation_builder.rb +56 -0
- data/lib/whyvalidationssuckin96/validation_support.rb +74 -0
- data/lib/whyvalidationssuckin96.rb +4 -0
- data/test/attribute_based_validation_test.rb +58 -0
- data/test/macros/validates_acceptance_test.rb +64 -0
- data/test/macros/validates_associated_test.rb +60 -0
- data/test/macros/validates_confirmation_test.rb +63 -0
- data/test/macros/validates_exclusion_test.rb +37 -0
- data/test/macros/validates_format_test.rb +43 -0
- data/test/macros/validates_inclusion_test.rb +37 -0
- data/test/macros/validates_length_test.rb +179 -0
- data/test/macros/validates_numericality_test.rb +129 -0
- data/test/macros/validates_presence_test.rb +31 -0
- data/test/rails/active_record_test.rb +187 -0
- data/test/rails/active_record_test_helper.rb +90 -0
- data/test/rails/macros/validates_uniqueness_test.rb +153 -0
- data/test/skippable_validation_test.rb +102 -0
- data/test/teststrap.rb +4 -0
- data/test/validation_builder_test.rb +62 -0
- data/test/validation_support_test.rb +209 -0
- data/test/validation_test.rb +101 -0
- data/whyvalidationssuckin96.gemspec +153 -0
- metadata +189 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<meta name="Content-Type" content="text/html; charset=UTF-8" />
|
6
|
+
<title>Top Level Namespace</title>
|
7
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
|
8
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
|
9
|
+
|
10
|
+
<script type="text/javascript" charset="utf-8">
|
11
|
+
relpath = '';
|
12
|
+
if (relpath != '') relpath += '/';
|
13
|
+
</script>
|
14
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
15
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
16
|
+
|
17
|
+
</head>
|
18
|
+
<body>
|
19
|
+
<div id="header">
|
20
|
+
<div id="menu">
|
21
|
+
|
22
|
+
<a href="_index.html">Index</a> »
|
23
|
+
|
24
|
+
|
25
|
+
<span class="title">Top Level Namespace</span>
|
26
|
+
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div id="search">
|
30
|
+
<a id="class_list_link" href="#">Namespace List</a>
|
31
|
+
<a id="method_list_link" href="#">Method List</a>
|
32
|
+
<a id ="file_list_link" href="#">File List</a>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="clear"></div>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<iframe id="search_frame"></iframe>
|
39
|
+
|
40
|
+
<div id="content"><h1>Top Level Namespace
|
41
|
+
|
42
|
+
|
43
|
+
</h1>
|
44
|
+
|
45
|
+
<dl class="box">
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
</dl>
|
54
|
+
<div class="clear"></div>
|
55
|
+
|
56
|
+
<h2>Defined Under Namespace</h2>
|
57
|
+
<p class="children">
|
58
|
+
|
59
|
+
|
60
|
+
<strong class="modules">Modules:</strong> <a href="ActiveRecord.html" title="ActiveRecord">ActiveRecord</a>, <a href="WhyValidationsSuckIn96.html" title="WhyValidationsSuckIn96">WhyValidationsSuckIn96</a>
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
<strong class="classes">Classes:</strong> <a href="FalseClass.html" title="FalseClass">FalseClass</a>, <a href="NilClass.html" title="NilClass">NilClass</a>, <a href="Numeric.html" title="Numeric">Numeric</a>, <a href="Object.html" title="Object">Object</a>, <a href="String.html" title="String">String</a>, <a href="TrueClass.html" title="TrueClass">TrueClass</a>
|
65
|
+
|
66
|
+
|
67
|
+
</p>
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
</div>
|
73
|
+
|
74
|
+
<div id="footer">
|
75
|
+
Generated on Sun Dec 20 19:49:47 2009 by
|
76
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool">yard</a>
|
77
|
+
0.5.2 (ruby-1.8.7).
|
78
|
+
</div>
|
79
|
+
|
80
|
+
</body>
|
81
|
+
</html>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module WhyValidationsSuckIn96
|
2
|
+
# A mixin to help handle the most common case of validating a single attribute on an object. This module has a
|
3
|
+
# dependency on SkippableValidation that will most likely be removed in future releases, but is something to be
|
4
|
+
# aware of currently.
|
5
|
+
module AttributeBasedValidation
|
6
|
+
|
7
|
+
# An initializer for a validation that checks to see if the required options have been passed for
|
8
|
+
# attribute based validation to work as expected.
|
9
|
+
# @param [Object] validatable An object to be validated
|
10
|
+
# @param [Hash] options The options to set up the validation with
|
11
|
+
# @option options [Symbol] :attribute The attribute on the validatable object to validate against
|
12
|
+
# @option options [true, false] :allow_nil If true, skips validation of the value of the attribute is #nil?
|
13
|
+
# @option options [true, false] :allow_blank If true, skips validation of the value of the attribute is #blank?
|
14
|
+
def initialize(validatable, options = {})
|
15
|
+
raise(ArgumentError, "The attribute to validate must be specified as :attribute") unless options[:attribute]
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
# The attribute to validate against
|
20
|
+
def attribute
|
21
|
+
options[:attribute]
|
22
|
+
end
|
23
|
+
|
24
|
+
# The value of the attribute to validate against
|
25
|
+
def attribute_value
|
26
|
+
validatable.send(options[:attribute])
|
27
|
+
end
|
28
|
+
|
29
|
+
# A default validate implementation that skips on #nil?/#blank? attribute values if :allow_nil or :allow_blank
|
30
|
+
# have been set.
|
31
|
+
def validate
|
32
|
+
skip if skip_on_blank? || skip_on_nil?
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def skip_on_nil?
|
39
|
+
options[:allow_nil] && attribute_value.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def skip_on_blank?
|
43
|
+
options[:allow_blank] && attribute_value.blank?
|
44
|
+
end
|
45
|
+
end # AttributeBasedValidation
|
46
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Object
|
2
|
+
unless instance_methods(false).include?("blank?")
|
3
|
+
def blank?
|
4
|
+
respond_to?(:empty?) ? empty? : !self
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class String
|
10
|
+
unless instance_methods(false).include?("blank?")
|
11
|
+
def blank?
|
12
|
+
self !~ /\S/
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Numeric
|
18
|
+
unless instance_methods(false).include?("blank?")
|
19
|
+
def blank?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class TrueClass
|
26
|
+
unless instance_methods(false).include?("blank?")
|
27
|
+
def blank?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class FalseClass
|
34
|
+
unless instance_methods(false).include?("blank?")
|
35
|
+
def blank?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class NilClass
|
42
|
+
unless instance_methods(false).include?("blank?")
|
43
|
+
def blank?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Validates the acceptance of an attribute, such as the "I agree to the terms and conditions" checkbox value returned
|
7
|
+
# by a form post.
|
8
|
+
#
|
9
|
+
# @example Default usage
|
10
|
+
# setup_validations do
|
11
|
+
# validates_acceptance_of :privacy_policy, :terms_and_conditions
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @example Changing the :accept value
|
15
|
+
# setup_validations do
|
16
|
+
# validates_acceptance_of :privacy_policy, :accept => "yep"
|
17
|
+
# end
|
18
|
+
class ValidatesAcceptance < Validation
|
19
|
+
DefaultOptions = {:allow_nil => true, :accept => "1", :message => "must be accepted"}
|
20
|
+
|
21
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
22
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
23
|
+
|
24
|
+
def validate
|
25
|
+
super
|
26
|
+
if options[:accept] == attribute_value
|
27
|
+
pass
|
28
|
+
else
|
29
|
+
fail
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end # Validation
|
34
|
+
|
35
|
+
ValidationBuilder.register_macro :validates_acceptance_of, WhyValidationsSuckIn96::ValidatesAcceptance
|
36
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks the validity of any associated objects, such as an ActiveRecord association.
|
7
|
+
#
|
8
|
+
# @example Checking the validity of an associated collection of tracks
|
9
|
+
# setup_validations do
|
10
|
+
# validates_associated :tracks
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @example Checking the validity of an associated artist
|
14
|
+
# setup_validations do
|
15
|
+
# validates_associated :artist
|
16
|
+
# end
|
17
|
+
class ValidatesAssociated < Validation
|
18
|
+
DefaultOptions = {:message => "is invalid"}
|
19
|
+
|
20
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
21
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
22
|
+
|
23
|
+
def validate
|
24
|
+
super
|
25
|
+
Array(attribute_value).collect do |assoc|
|
26
|
+
assoc.valid?
|
27
|
+
end.all? ? pass : fail
|
28
|
+
end
|
29
|
+
|
30
|
+
end # Validation
|
31
|
+
|
32
|
+
ValidationBuilder.register_macro :validates_associated, WhyValidationsSuckIn96::ValidatesAssociated
|
33
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks the validity of an attribute against a confirmation field. Note that this validation does
|
7
|
+
# not set up the confirmation field on the object, leaving this up to the implementer.
|
8
|
+
#
|
9
|
+
# @example Default usage
|
10
|
+
# class Account
|
11
|
+
# attr_accessor :password, :password_confirmation
|
12
|
+
# setup_validations do
|
13
|
+
# validates_confirmation_of :password
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
class ValidatesConfirmation < Validation
|
17
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
18
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
19
|
+
|
20
|
+
DefaultOptions = {:message => "does not match the confirmation"}
|
21
|
+
|
22
|
+
def validate
|
23
|
+
super
|
24
|
+
skip unless confirmation_value = validatable.send(confirmation_field)
|
25
|
+
if confirmation_value == attribute_value
|
26
|
+
pass
|
27
|
+
else
|
28
|
+
fail
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def confirmation_field
|
35
|
+
:"#{attribute}_confirmation"
|
36
|
+
end
|
37
|
+
end # Validation
|
38
|
+
|
39
|
+
ValidationBuilder.register_macro :validates_confirmation_of, WhyValidationsSuckIn96::ValidatesAcceptance
|
40
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks the validity of an attribute against a collection of excluded values.
|
7
|
+
#
|
8
|
+
# @example Default usage
|
9
|
+
# setup_validations do
|
10
|
+
# validates_exclusion_of :subdomain, :in => %w[www ftp]
|
11
|
+
# end
|
12
|
+
class ValidatesExclusion < Validation
|
13
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
14
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
15
|
+
|
16
|
+
DefaultOptions = {:message => "is in the excluded collection"}
|
17
|
+
|
18
|
+
# @param [Object] validatable An object to be validated.
|
19
|
+
# @param [Hash] options The options to set up the validation with.
|
20
|
+
# @option options [#include?] :in A collection to check against for exclusion.
|
21
|
+
def initialize(validatable, options = {})
|
22
|
+
super
|
23
|
+
raise(ArgumentError, "Collection to check for exclusion against should be specified with :in") unless options[:in]
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate
|
27
|
+
super
|
28
|
+
if options[:in].include?(attribute_value)
|
29
|
+
fail
|
30
|
+
else
|
31
|
+
pass
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end # Validation
|
36
|
+
|
37
|
+
ValidationBuilder.register_macro :validates_exclusion_of, WhyValidationsSuckIn96::ValidatesExclusion
|
38
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks the validity of an attribute against a regular expression.
|
7
|
+
#
|
8
|
+
# @example Default usage
|
9
|
+
# setup_validations do
|
10
|
+
# validates_format_of :username, :with => /[a-z0-9]/i
|
11
|
+
# end
|
12
|
+
class ValidatesFormat < Validation
|
13
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
14
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
15
|
+
|
16
|
+
DefaultOptions = {:message => "does not match the given format"}
|
17
|
+
|
18
|
+
# @param [Object] validatable An object to be validated
|
19
|
+
# @param [Hash] options The options to set up the validation with
|
20
|
+
# @option options [Regexp] :with A regular expression to check against
|
21
|
+
def initialize(validatable, options = {})
|
22
|
+
super
|
23
|
+
raise(ArgumentError, "Regular expression to check against must be given as :with") unless options[:with]
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate
|
27
|
+
super
|
28
|
+
if attribute_value.to_s =~ options[:with]
|
29
|
+
pass
|
30
|
+
else
|
31
|
+
fail
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end # Validation
|
36
|
+
|
37
|
+
ValidationBuilder.register_macro :validates_format_of, WhyValidationsSuckIn96::ValidatesFormat
|
38
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks the validity of an attribute against a list of values for it to be included in.
|
7
|
+
#
|
8
|
+
# @example Default usage
|
9
|
+
# setup_validations do
|
10
|
+
# validates_inclusion_of :unit_system, :in => %w[imperial metric]
|
11
|
+
# end
|
12
|
+
class ValidatesInclusion < Validation
|
13
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
14
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
15
|
+
|
16
|
+
DefaultOptions = {:message => "is not in the acceptable collection"}
|
17
|
+
|
18
|
+
# @param [Object] validatable An object to be validated.
|
19
|
+
# @param [Hash] options The options to set up the validation with.
|
20
|
+
# @option options [#include?] :in A collection to check against for inclusion.
|
21
|
+
def initialize(validatable, options = {})
|
22
|
+
super
|
23
|
+
raise(ArgumentError, "Collection to check for inclusion against should be specified with :in") unless options[:in]
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate
|
27
|
+
super
|
28
|
+
if options[:in].include?(attribute_value)
|
29
|
+
pass
|
30
|
+
else
|
31
|
+
fail
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end # Validation
|
36
|
+
|
37
|
+
ValidationBuilder.register_macro :validates_inclusion_of, WhyValidationsSuckIn96::ValidatesInclusion
|
38
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks the validity of an attribute against a given set of sizes.
|
7
|
+
#
|
8
|
+
# @example Checking against an exact value
|
9
|
+
# setup_validations do
|
10
|
+
# validates_length_of :choices, :is => 4
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @example Checking against a range
|
14
|
+
# setup_validations do
|
15
|
+
# validates_length_of :choices, :in => 1..10
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# @example Checking against a minimum value
|
19
|
+
# setup_validations do
|
20
|
+
# validates_length_of :choices, :minimum => 1
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# @example Checking against a maximum value
|
24
|
+
# setup_validations do
|
25
|
+
# validates_length_of :choices, :maximum => 10
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @example Checking against a minimum and maximum value
|
29
|
+
# setup_validations do
|
30
|
+
# validates_length_of :choices, :minimum => 1, :maximum => 10
|
31
|
+
# end
|
32
|
+
class ValidatesLength < Validation
|
33
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
34
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
35
|
+
|
36
|
+
DefaultOptions = {:message => "does not meet the given length restrictions"}
|
37
|
+
ValidOptions = [:is, :in, :minimum, :maximum]
|
38
|
+
OptionIncompatibility = {
|
39
|
+
:is => [:minimum, :maximum, :in],
|
40
|
+
:in => [:minimum, :maximum, :is]
|
41
|
+
}
|
42
|
+
|
43
|
+
# @param [Object] validatable An object to be validated.
|
44
|
+
# @param [Hash] options The options to set up the validation with.
|
45
|
+
# @option options [#==] :is An exact value to check the validatable object's #size against.
|
46
|
+
# @option options [#include?] :in A range to check the validatable object's #size against.
|
47
|
+
# @option options [#<=] :minimum A minimum value to check the validatable object's size against.
|
48
|
+
# @option options [#>=] :maximum A maximum value to check the validatable object's size against.
|
49
|
+
def initialize(validatable, options = {})
|
50
|
+
super
|
51
|
+
check_options(options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def validate
|
55
|
+
super
|
56
|
+
all_valid = ValidOptions.collect do |opt_name|
|
57
|
+
next(true) if options[opt_name].nil?
|
58
|
+
send(:"validate_#{opt_name}")
|
59
|
+
end.all?
|
60
|
+
all_valid ? pass : fail
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def validate_is
|
66
|
+
options[:is] == attribute_value.size
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_in
|
70
|
+
options[:in].include?(attribute_value.size)
|
71
|
+
end
|
72
|
+
|
73
|
+
def validate_minimum
|
74
|
+
options[:minimum] <= attribute_value.size
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_maximum
|
78
|
+
options[:maximum] >= attribute_value.size
|
79
|
+
end
|
80
|
+
|
81
|
+
def check_options(options_hash)
|
82
|
+
OptionIncompatibility.each do |opt,incompat|
|
83
|
+
next unless options_hash[opt]
|
84
|
+
bad_opt = incompat.detect { |opt_name| options_hash.keys.include?(opt_name) }
|
85
|
+
if bad_opt
|
86
|
+
names = [opt.inspect.to_s, bad_opt.inspect.to_s].sort
|
87
|
+
raise(ArgumentError, "Option #{names.first} can not be mixed with #{names.last}")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
raise(ArgumentError, "Length options must be given as :minimum, :maximum, :is, or :in") unless options_hash.keys.any? do |opt|
|
91
|
+
ValidOptions.include?(opt)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end # Validation
|
96
|
+
|
97
|
+
ValidationBuilder.register_macro :validates_length_of, WhyValidationsSuckIn96::ValidatesLength
|
98
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks to see if a given attribute is a valid numerical value. Allows a certain degree of latitude in determining
|
7
|
+
# what is a valid numerical value, like allowing commas and spaces in the value for example.
|
8
|
+
#
|
9
|
+
# @example Default usage
|
10
|
+
# setup_validations do
|
11
|
+
# validates_numericality_of :cost
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @example Only allow integer values
|
15
|
+
# setup_validations do
|
16
|
+
# validates_numericality_of :cost, :only_integer => true
|
17
|
+
# end
|
18
|
+
class ValidatesNumericality < Validation
|
19
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
20
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
21
|
+
|
22
|
+
DefaultOptions = {:message => "is not a numerical value"}
|
23
|
+
StripNonNumeric = /[^-+e\d.]/im
|
24
|
+
ValidNumericChars = /\A[-+e\d.,\s]+\Z/im
|
25
|
+
|
26
|
+
def validate
|
27
|
+
super
|
28
|
+
if options[:only_integer]
|
29
|
+
validate_as_integer
|
30
|
+
else
|
31
|
+
validate_as_float
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def validate_as_integer
|
38
|
+
fail if attribute_value.to_s !~ ValidNumericChars
|
39
|
+
Integer(attribute_value.to_s.gsub(StripNonNumeric, ""))
|
40
|
+
pass
|
41
|
+
rescue ArgumentError, TypeError
|
42
|
+
fail
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate_as_float
|
46
|
+
fail if attribute_value.to_s !~ ValidNumericChars
|
47
|
+
Kernel.Float(attribute_value.to_s.gsub(StripNonNumeric, ""))
|
48
|
+
pass
|
49
|
+
rescue ArgumentError, TypeError
|
50
|
+
fail
|
51
|
+
end
|
52
|
+
|
53
|
+
end # Validation
|
54
|
+
|
55
|
+
ValidationBuilder.register_macro :validates_numericality_of, WhyValidationsSuckIn96::ValidatesNumericality
|
56
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'whyvalidationssuckin96/skippable_validation'
|
2
|
+
require 'whyvalidationssuckin96/attribute_based_validation'
|
3
|
+
|
4
|
+
module WhyValidationsSuckIn96
|
5
|
+
|
6
|
+
# Checks for the presence of a given attribute.
|
7
|
+
#
|
8
|
+
# @example Default usage
|
9
|
+
# setup_validations do
|
10
|
+
# validates_presence_of :name
|
11
|
+
# end
|
12
|
+
class ValidatesPresence < Validation
|
13
|
+
include WhyValidationsSuckIn96::SkippableValidation
|
14
|
+
include WhyValidationsSuckIn96::AttributeBasedValidation
|
15
|
+
|
16
|
+
DefaultOptions = {:message => "is not present"}
|
17
|
+
|
18
|
+
def validate
|
19
|
+
super
|
20
|
+
if attribute_value.blank?
|
21
|
+
fail
|
22
|
+
else
|
23
|
+
pass
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end # Validation
|
28
|
+
|
29
|
+
ValidationBuilder.register_macro :validates_presence_of, WhyValidationsSuckIn96::ValidatesPresence
|
30
|
+
end # WhyValidationsSuckIn96
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'whyvalidationssuckin96/macros/validates_acceptance'
|
2
|
+
require 'whyvalidationssuckin96/macros/validates_associated'
|
3
|
+
require 'whyvalidationssuckin96/macros/validates_confirmation'
|
4
|
+
require 'whyvalidationssuckin96/macros/validates_exclusion'
|
5
|
+
require 'whyvalidationssuckin96/macros/validates_format'
|
6
|
+
require 'whyvalidationssuckin96/macros/validates_inclusion'
|
7
|
+
require 'whyvalidationssuckin96/macros/validates_length'
|
8
|
+
require 'whyvalidationssuckin96/macros/validates_numericality'
|
9
|
+
require 'whyvalidationssuckin96/macros/validates_presence'
|