validatious-on-rails 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/Rakefile +52 -0
  2. data/generators/validatious/templates/v2.standalone.full.min.js +7 -0
  3. data/generators/validatious/templates/validatious.config.js +83 -0
  4. data/generators/validatious/validatious_generator.rb +12 -0
  5. data/lib/validatious-on-rails/helpers.rb +20 -0
  6. data/lib/validatious-on-rails/model_validations.rb +312 -0
  7. data/lib/validatious-on-rails/rails/action_view_helpers.rb +114 -0
  8. data/lib/validatious-on-rails/rails.rb +2 -0
  9. data/lib/validatious-on-rails/validatious/client_side_validator.rb +14 -0
  10. data/lib/validatious-on-rails/validatious/remote_validator.rb +24 -0
  11. data/lib/validatious-on-rails/validatious/validator.rb +228 -0
  12. data/lib/validatious-on-rails/validatious/validators/exclusion_validator.rb +28 -0
  13. data/lib/validatious-on-rails/validatious/validators/format_validator.rb +33 -0
  14. data/lib/validatious-on-rails/validatious/validators/inclusion_validator.rb +28 -0
  15. data/lib/validatious-on-rails/validatious/validators/length/is_validator.rb +27 -0
  16. data/lib/validatious-on-rails/validatious/validators/length/maximum_validator.rb +27 -0
  17. data/lib/validatious-on-rails/validatious/validators/length/minimum_validator.rb +27 -0
  18. data/lib/validatious-on-rails/validatious/validators/numericality/equal_to_validator.rb +25 -0
  19. data/lib/validatious-on-rails/validatious/validators/numericality/even_validator.rb +24 -0
  20. data/lib/validatious-on-rails/validatious/validators/numericality/greater_than_or_equal_to_validator.rb +25 -0
  21. data/lib/validatious-on-rails/validatious/validators/numericality/greater_than_validator.rb +25 -0
  22. data/lib/validatious-on-rails/validatious/validators/numericality/less_than_or_equal_to_validator.rb +25 -0
  23. data/lib/validatious-on-rails/validatious/validators/numericality/less_than_validator.rb +25 -0
  24. data/lib/validatious-on-rails/validatious/validators/numericality/odd_validator.rb +24 -0
  25. data/lib/validatious-on-rails/validatious/validators/numericality/only_integer_validator.rb +24 -0
  26. data/lib/validatious-on-rails/validatious/validators.rb +3 -0
  27. data/lib/validatious-on-rails/validatious.rb +5 -0
  28. data/lib/validatious-on-rails.rb +41 -0
  29. data/rails/init.rb +2 -0
  30. data/test/test_helper.rb +93 -0
  31. data/test/validatious_on_rails/helpers_test.rb +47 -0
  32. data/test/validatious_on_rails/model_validations_test.rb +190 -0
  33. data/test/validatious_on_rails/rails/action_view_helpers_test.rb +168 -0
  34. data/test/validatious_on_rails/validatious/validator_test.rb +56 -0
  35. data/test/validatious_on_rails_test.rb +6 -0
  36. metadata +129 -0
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), 'validator')
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ class ClientSideValidator < Validator
7
+
8
+ def initialize(name, *args)
9
+ super
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), 'validator')
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ class RemoteValidator < Validator
7
+
8
+ def initialize(name, *args)
9
+ super
10
+ end
11
+
12
+ # TODO: Implement server side validator class, i.e. for validatios that requires AJAX
13
+
14
+ # Idea:
15
+ #
16
+ # Perform AJAX-request to a specified/generated URL
17
+ # (e.g. /validatious/unique?model=article&attribute=...&value=...), with an attached
18
+ # callback-method that should trigger a client-side validation.
19
+ # Well, this is one possible approach...
20
+ #
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,228 @@
1
+ # encoding: utf-8
2
+
3
+ # Ruby-representation of a custom Validatious validator ("v2.Validator").
4
+ #
5
+ # Example (JavaScript representation):
6
+ #
7
+ # v2.Validator.add(
8
+ # name: 'validator-name',
9
+ # message: 'Default error message',
10
+ # params: ['a', 'list', 'of', 'named', 'parameters'],
11
+ # aliases: ['list', 'of', 'alternative', 'names'],
12
+ # acceptEmpty: true,
13
+ # fn: function(field, value, params) {
14
+ # // Should return true if field/value is valid
15
+ # }
16
+ # });
17
+ #
18
+ module ValidatiousOnRails
19
+ module Validatious
20
+ class Validator
21
+
22
+ # Reference: http://validatious.org/learn/features/core/custom_validators
23
+
24
+ ValidatorError = ::Class.new(::StandardError) unless defined?(ValidatorError)
25
+
26
+ attr_accessor :name
27
+ attr_writer :message,
28
+ :params,
29
+ :aliases,
30
+ :accept_empty,
31
+ :fn
32
+
33
+ def initialize(name, options = {})
34
+ raise ValidatorError, "Parameter :name is required for an Validatious validator" unless name.present?
35
+ self.name = name
36
+ options.each do |attr, value|
37
+ self.send(:"#{attr}=", value) if value.present?
38
+ end
39
+ end
40
+
41
+ # The primary name of the validator. This is the name you use with v2.$v('name');
42
+ # and v2.Validator.get('name'); (core API), "field".is("name"); (DSL API) and
43
+ # class="name" (HTML extension).
44
+ #
45
+ # Parameter is required.
46
+ #
47
+ # def name
48
+ # @name
49
+ # end
50
+
51
+ # This is the default error message. It may use named parameters.
52
+ # Parameters can be interpolated into the default message through ${param-name}.
53
+ # All messages have access to ${field}, which resolves to the field name of
54
+ # he validated field.
55
+ #
56
+ # If the validator takes any parameters, they can also be interpolated into the
57
+ # message, through the name given through the params parameter.
58
+ #
59
+ def message
60
+ @message ||= ''
61
+ end
62
+
63
+ # The params parameter provides a mapping between any parameters being sent to
64
+ # the validation method and names to refer to them by when interpolating in the
65
+ # error message.
66
+ #
67
+ # Example: If the fn function uses the value in params[0], you may give this a
68
+ # name by setting params: ['myparam']. In the error message you can then do
69
+ # message: "${field} should obey ${myparam}". When a field fails this message,
70
+ # ${field} will be replaced with the field name, and ${myparam} with the value
71
+ # of the validator function's params[0].
72
+ #
73
+ def params
74
+ @params ||= []
75
+ end
76
+
77
+ # An array of additional names for the validator. May make sense especially for
78
+ # the DSL API to be able to refer to a validator by different names.
79
+ #
80
+ def aliases
81
+ @aliases ||= []
82
+ end
83
+
84
+ # Decides if the validator should pass (return true) when the value is empty.
85
+ # This is usually a good idea because you can leave it up to the required validator
86
+ # to specifically check for emptiness. One benefit of this approach is more
87
+ # fine grained error reporting, helping the user.
88
+ #
89
+ # Default value is: true.
90
+ #
91
+ def accept_empty
92
+ @accept_empty.nil? ? true : @accept_empty
93
+ end
94
+
95
+ # This is the method that performs the validation. It receives three arguments,
96
+ # the last one (parameters) may be empty.
97
+ #
98
+ # 1. field is an instance of v2.InputElement, or one of its subclasses. It wraps a
99
+ # label and one or more input/select/textarea elements, and provides convenience
100
+ # such as getValue, getLabel, getName, setName, visible and getParent.
101
+ #
102
+ # 2. value is basically the value of field.getValue(). There is some overhead in
103
+ # fetching the value, and since Validatious already uses it, it passes it along,
104
+ # allowing for an ever so small performance gain.
105
+ #
106
+ # 3. params is an array of parameters registered with the field validator. In the
107
+ # HTML extension, these are the values separated by underscores:
108
+ # class="myval_1" (params[0] === 1).
109
+ #
110
+ # Parameter is required.
111
+ #
112
+ def fn=(value)
113
+ # Handle either full function definition, or just the function body - just because.
114
+ @fn = if (value =~ /function\(\w*,\w*,\w*\).*\{.*\}/i)
115
+ value
116
+ else
117
+ value ||= ''
118
+ # If no function specified yet, always validate true by default.
119
+ value << "\nreturn true;" unless value =~ /return (.+)/i
120
+ "function(field, value, params) {#{value}}"
121
+ end
122
+ end
123
+
124
+ def fn
125
+ (@fn ||= "function(field, value, params) {return true;}").gsub(/[\n\t]/, '')
126
+ end
127
+
128
+ def to_s
129
+ options = {
130
+ :name => self.name,
131
+ :message => self.message,
132
+ :params => self.params,
133
+ :aliases => self.aliases,
134
+ :acceptEmpty => self.accept_empty,
135
+ :fn => self.fn
136
+ }
137
+ # Just to make the tests much DRYer and maintanable on Ruby 1.8
138
+ # - hash ordered by key only 1.9. ='(
139
+ js_options = options.keys.collect(&:to_s).sort.collect { |k|
140
+ v = options[k.to_sym]
141
+ ("#{k}: #{k.to_sym == :fn ? v : v.to_json}" if [false, true].include?(v) || v.present?)
142
+ }.compact.join(', ')
143
+ "v2.Validator.add({#{js_options}});"
144
+ end
145
+
146
+ class << self
147
+
148
+ # Generate a unique valdiator ID to avoid clashes.
149
+ # Note: Ruby #hash is way faster than SHA1 (etc.) - just replace any negative sign.
150
+ #
151
+ def generate_id(value)
152
+ value.to_s.hash.to_s.tr('-', '1')
153
+ end
154
+
155
+ # Any named specified for this custom validation?
156
+ # E.g. validates_format_of :name, :with => /\d{6}-\d{4}/, :name => 'ssn-se'
157
+ #
158
+ # If not, create one that's uniqe based on validation and what to validate based on,
159
+ # e.g. validates_format_of :name, :with => /\d{6}-\d{4}/ # => :name => "format_with_#{hash-of-:with-value}"
160
+ #
161
+ def generate_name(validation, id_key, id_value = nil)
162
+ # Avoiding duplicates...
163
+ identifier = "-#{id_value}" if id_value.present?
164
+ validator_id = "#{validation.macro.to_s.sub(/^validates_/, '').sub(/_of/, '')}_#{id_key}#{identifier}"
165
+ name = validation.options[:name].present? ? validation.options[:name] : validator_id
166
+ # "_" is not allowed in name/alias(es) - used to seperate validator-id from it's args/params.
167
+ [name, validator_id].collect! { |v| v.tr('_', '-') }
168
+ end
169
+
170
+ # Generate proper error message using explicit message, or I18n-lookup.
171
+ # Core validations gets treated by Rails - unless explicit message is set that is.
172
+ #
173
+ # NOTE: Might refactor this into a even more abstract class/module.
174
+ #
175
+ def generate_message(validation, *args)
176
+ options = args.extract_options!
177
+ explicit_message = validation.options[:message]
178
+ key = options.delete(:key) || (explicit_message if explicit_message.is_a?(::Symbol))
179
+
180
+ message = if key.present?
181
+ ::I18n.t(key, options.merge(:scope => :'activerecord.errors.messages',
182
+ :default => "activerecord.errors.messages.#{key}"))
183
+ elsif explicit_message.is_a?(::String)
184
+ explicit_message
185
+ else
186
+ unless ::ValidatiousOnRails::ModelValidations::CORE_VALIDATIONS.include?(validation.macro.to_sym)
187
+ # No core validation, try to make up a descent I18n lookup path using conventions.
188
+ key ||= validation.macro.to_s.tr('-', '_').gsub(/^validates?_/, '').gsub(/_of/, '').to_sym
189
+ ::I18n.t(key, options.merge(:scope => :'activerecord.errors.messages',
190
+ :default => "activerecord.errors.messages.#{key}"))
191
+ else
192
+ # Nothing - let Rails rails handle the core validation message translations (I18n).
193
+ end
194
+ end
195
+ # Rails I18n interpolations => Validatious interpolations
196
+ # Example: {{count}} => ${count}
197
+ message.gsub(/\{\{/, '${').gsub(/\}\}/, '}')
198
+ end
199
+
200
+ # Rails core validation messages:
201
+ #
202
+ # messages:
203
+ # inclusion: "is not included in the list"
204
+ # exclusion: "is reserved"
205
+ # invalid: "is invalid"
206
+ # confirmation: "doesn't match confirmation"
207
+ # accepted: "must be accepted"
208
+ # empty: "can't be empty"
209
+ # blank: "can't be blank"
210
+ # too_long: "is too long (maximum is {{count}} characters)"
211
+ # too_short: "is too short (minimum is {{count}} characters)"
212
+ # wrong_length: "is the wrong length (should be {{count}} characters)"
213
+ # taken: "has already been taken"
214
+ # not_a_number: "is not a number"
215
+ # greater_than: "must be greater than {{count}}"
216
+ # greater_than_or_equal_to: "must be greater than or equal to {{count}}"
217
+ # equal_to: "must be equal to {{count}}"
218
+ # less_than: "must be less than {{count}}"
219
+ # less_than_or_equal_to: "must be less than or equal to {{count}}"
220
+ # odd: "must be odd"
221
+ # even: "must be even"
222
+ # record_invalid: "is invalid"
223
+
224
+ end
225
+
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. validator]))
3
+
4
+ # TODO: See notes in FormatValidator.
5
+ #
6
+ module ValidatiousOnRails
7
+ module Validatious
8
+ class ExclusionValidator < ClientSideValidator
9
+
10
+ def initialize(validation, options = {})
11
+ name, alias_name = self.class.generate_name(validation, :in, self.class.generate_id(validation.options[:in].inspect))
12
+ super name, options
13
+ self.aliases = [alias_name] - [name]
14
+ self.message = self.class.generate_message(validation)
15
+ self.accept_empty = validation.options[:allow_blank] || validation.options[:allow_nil]
16
+ self.fn = %{
17
+ var exclusion_values = #{validation.options[:in].to_json};
18
+ for (var i = 0; i < exclusion_values.length; i++) {
19
+ if (exclusion_values[i] == value) { return false; }
20
+ };
21
+ return true;
22
+ }
23
+ self.fn.freeze
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. validator]))
3
+
4
+ # TODO: Would be "cool" if each format rule was save as a JS var,
5
+ # and referenced with class Validatious style:
6
+ #
7
+ # <head>:
8
+ # var ssn-se = /^\d{6}-{4}$/;
9
+ # <<< format validator here >>>
10
+ # <body>:
11
+ # <input type="text" class="format-with_ssn-se" ... />
12
+ #
13
+ # Same for inclusion/exclusion too. Easy to implement, but low prio.
14
+ #
15
+ module ValidatiousOnRails
16
+ module Validatious
17
+ class FormatValidator < ClientSideValidator
18
+
19
+ def initialize(validation, options = {})
20
+ name, alias_name = self.class.generate_name(validation, :with, self.class.generate_id(validation.options[:with].inspect))
21
+ super name, options
22
+ self.aliases = [alias_name] - [name]
23
+ self.message = self.class.generate_message(validation)
24
+ self.accept_empty = validation.options[:allow_blank] || validation.options[:allow_nil]
25
+ self.fn = %{
26
+ return #{validation.options[:with].inspect}.test(value);
27
+ }
28
+ self.fn.freeze
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. validator]))
3
+
4
+ # TODO: See notes in FormatValidator.
5
+ #
6
+ module ValidatiousOnRails
7
+ module Validatious
8
+ class InclusionValidator < ClientSideValidator
9
+
10
+ def initialize(validation, options = {})
11
+ name, alias_name = self.class.generate_name(validation, :in, self.class.generate_id(validation.options[:in].inspect))
12
+ super name, options
13
+ self.aliases = [alias_name] - [name]
14
+ self.message = self.class.generate_message(validation)
15
+ self.accept_empty = validation.options[:allow_blank] || validation.options[:allow_nil]
16
+ self.fn = %{
17
+ var inclusion_values = #{validation.options[:in].to_json};
18
+ for (var i = 0; i < inclusion_values.length; i++) {
19
+ if (inclusion_values[i] == value) { return true; }
20
+ };
21
+ return false;
22
+ }
23
+ self.fn.freeze
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Length
7
+ class IsValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name, alias_name = self.class.generate_name(validation, :is, validation.options[:is])
11
+ name = 'length-is'
12
+ super name, options
13
+ self.aliases = [alias_name] - [name]
14
+ self.params = ['count']
15
+ self.message = self.class.generate_message(validation, :key => :wrong_length)
16
+ self.accept_empty = validation.options[:allow_blank] || validation.options[:allow_nil]
17
+ self.fn = %{
18
+ value += '';
19
+ return value == params[0];
20
+ }
21
+ self.fn.freeze
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Length
7
+ class MaximumValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name, alias_name = self.class.generate_name(validation, :maximum, validation.options[:maximum])
11
+ name = 'length-maximum'
12
+ super name, options
13
+ self.aliases = [alias_name] - [name]
14
+ self.params = ['count']
15
+ self.message = self.class.generate_message(validation, :key => :too_long)
16
+ self.accept_empty = validation.options[:allow_blank] || validation.options[:allow_nil]
17
+ self.fn = %{
18
+ value += '';
19
+ return value.length <= params[0];
20
+ }
21
+ self.fn.freeze
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Length
7
+ class MinimumValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name, alias_name = self.class.generate_name(validation, :minimum, validation.options[:minimum])
11
+ name = 'length-minimum'
12
+ super name, options
13
+ self.aliases = [alias_name] - [name]
14
+ self.params = ['count']
15
+ self.message = self.class.generate_message(validation, :key => :too_short)
16
+ self.accept_empty = validation.options[:allow_blank] || validation.options[:allow_nil]
17
+ self.fn = %{
18
+ value += '';
19
+ return value.length >= params[0];
20
+ }
21
+ self.fn.freeze
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class EqualToValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-equal-to'
11
+ super name, options
12
+ self.params = ['count']
13
+ self.message = self.class.generate_message(validation, :key => :equal_to)
14
+ self.accept_empty = validation.options[:allow_nil]
15
+ self.fn = %{
16
+ value = +value;
17
+ return value == params[0];
18
+ }
19
+ self.fn.freeze
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class EvenValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-even'
11
+ super name, options
12
+ self.message = self.class.generate_message(validation, :key => :even)
13
+ self.accept_empty = validation.options[:allow_nil]
14
+ self.fn = %{
15
+ value = +value;
16
+ return (value % 2) == 0;
17
+ }
18
+ self.fn.freeze
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class GreaterThanOrEqualToValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-greater-than-or-equal-to'
11
+ super name, options
12
+ self.params = ['count']
13
+ self.message = self.class.generate_message(validation, :key => :greater_than_or_equal_to)
14
+ self.accept_empty = validation.options[:allow_nil]
15
+ self.fn = %{
16
+ value = +value;
17
+ return value >= params[0];
18
+ }
19
+ self.fn.freeze
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class GreaterThanValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-greater-than'
11
+ super name, options
12
+ self.params = ['count']
13
+ self.message = self.class.generate_message(validation, :key => :greater_than)
14
+ self.accept_empty = validation.options[:allow_nil]
15
+ self.fn = %{
16
+ value = +value;
17
+ return value > params[0];
18
+ }
19
+ self.fn.freeze
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class LessThanOrEqualToValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-less-than-or-equal-to'
11
+ super name, options
12
+ self.params = ['count']
13
+ self.message = self.class.generate_message(validation, :key => :less_than_or_equal_to)
14
+ self.accept_empty = validation.options[:allow_nil]
15
+ self.fn = %{
16
+ value = +value;
17
+ return value <= params[0];
18
+ }
19
+ self.fn.freeze
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class LessThanValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-less-than'
11
+ super name, options
12
+ self.params = ['count']
13
+ self.message = self.class.generate_message(validation, :key => :less_than)
14
+ self.accept_empty = validation.options[:allow_nil]
15
+ self.fn = %{
16
+ value = +value;
17
+ return value < params[0];
18
+ }
19
+ self.fn.freeze
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class OddValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-odd'
11
+ super name, options
12
+ self.message = self.class.generate_message(validation, :key => :odd)
13
+ self.accept_empty = validation.options[:allow_nil]
14
+ self.fn = %{
15
+ value = +value;
16
+ return (value % 2) == 1;
17
+ }
18
+ self.fn.freeze
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. validator]))
3
+
4
+ module ValidatiousOnRails
5
+ module Validatious
6
+ module Numericality
7
+ class OnlyIntegerValidator < ClientSideValidator
8
+
9
+ def initialize(validation, options = {})
10
+ name = 'numericality-only_integer'
11
+ super name, options
12
+ self.message = self.class.generate_message(validation, :key => :not_a_number)
13
+ self.accept_empty = validation.options[:allow_nil]
14
+ self.fn = %{
15
+ value = +value;
16
+ return /\A[+-]?\d+\Z/.test(value);
17
+ }
18
+ self.fn.freeze
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ Dir.glob(File.join(File.dirname(__FILE__), 'validators', '**', '*.rb').to_s).each do |validator|
2
+ require validator
3
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), *%w[validatious validator])
3
+ require File.join(File.dirname(__FILE__), *%w[validatious client_side_validator])
4
+ require File.join(File.dirname(__FILE__), *%w[validatious remote_validator])
5
+ require File.join(File.dirname(__FILE__), *%w[validatious validators])