activemodel 3.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/CHANGELOG +13 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +216 -0
  4. data/lib/active_model.rb +61 -0
  5. data/lib/active_model/attribute_methods.rb +391 -0
  6. data/lib/active_model/callbacks.rb +133 -0
  7. data/lib/active_model/conversion.rb +19 -0
  8. data/lib/active_model/deprecated_error_methods.rb +33 -0
  9. data/lib/active_model/dirty.rb +164 -0
  10. data/lib/active_model/errors.rb +277 -0
  11. data/lib/active_model/lint.rb +89 -0
  12. data/lib/active_model/locale/en.yml +26 -0
  13. data/lib/active_model/naming.rb +60 -0
  14. data/lib/active_model/observing.rb +196 -0
  15. data/lib/active_model/railtie.rb +2 -0
  16. data/lib/active_model/serialization.rb +87 -0
  17. data/lib/active_model/serializers/json.rb +96 -0
  18. data/lib/active_model/serializers/xml.rb +204 -0
  19. data/lib/active_model/test_case.rb +16 -0
  20. data/lib/active_model/translation.rb +60 -0
  21. data/lib/active_model/validations.rb +168 -0
  22. data/lib/active_model/validations/acceptance.rb +51 -0
  23. data/lib/active_model/validations/confirmation.rb +49 -0
  24. data/lib/active_model/validations/exclusion.rb +40 -0
  25. data/lib/active_model/validations/format.rb +64 -0
  26. data/lib/active_model/validations/inclusion.rb +40 -0
  27. data/lib/active_model/validations/length.rb +98 -0
  28. data/lib/active_model/validations/numericality.rb +111 -0
  29. data/lib/active_model/validations/presence.rb +41 -0
  30. data/lib/active_model/validations/validates.rb +108 -0
  31. data/lib/active_model/validations/with.rb +70 -0
  32. data/lib/active_model/validator.rb +160 -0
  33. data/lib/active_model/version.rb +9 -0
  34. metadata +96 -0
@@ -0,0 +1,51 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class AcceptanceValidator < EachValidator
4
+ def initialize(options)
5
+ super(options.reverse_merge(:allow_nil => true, :accept => "1"))
6
+ end
7
+
8
+ def validate_each(record, attribute, value)
9
+ unless value == options[:accept]
10
+ record.errors.add(attribute, :accepted, :default => options[:message])
11
+ end
12
+ end
13
+
14
+ def setup(klass)
15
+ # Note: instance_methods.map(&:to_s) is important for 1.9 compatibility
16
+ # as instance_methods returns symbols unlike 1.8 which returns strings.
17
+ new_attributes = attributes.reject { |name| klass.instance_methods.map(&:to_s).include?("#{name}=") }
18
+ klass.send(:attr_accessor, *new_attributes)
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+ # Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:
24
+ #
25
+ # class Person < ActiveRecord::Base
26
+ # validates_acceptance_of :terms_of_service
27
+ # validates_acceptance_of :eula, :message => "must be abided"
28
+ # end
29
+ #
30
+ # If the database column does not exist, the +terms_of_service+ attribute is entirely virtual. This check is
31
+ # performed only if +terms_of_service+ is not +nil+ and by default on save.
32
+ #
33
+ # Configuration options:
34
+ # * <tt>:message</tt> - A custom error message (default is: "must be accepted").
35
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
36
+ # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is true).
37
+ # * <tt>:accept</tt> - Specifies value that is considered accepted. The default value is a string "1", which
38
+ # makes it easy to relate to an HTML checkbox. This should be set to +true+ if you are validating a database
39
+ # column, since the attribute is typecast from "1" to +true+ before validation.
40
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
41
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
42
+ # method, proc or string should return or evaluate to a true or false value.
43
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
44
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
45
+ # method, proc or string should return or evaluate to a true or false value.
46
+ def validates_acceptance_of(*attr_names)
47
+ validates_with AcceptanceValidator, _merge_attributes(attr_names)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,49 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class ConfirmationValidator < EachValidator
4
+ def validate_each(record, attribute, value)
5
+ confirmed = record.send(:"#{attribute}_confirmation")
6
+ return if confirmed.nil? || value == confirmed
7
+ record.errors.add(attribute, :confirmation, :default => options[:message])
8
+ end
9
+
10
+ def setup(klass)
11
+ klass.send(:attr_accessor, *attributes.map { |attribute| :"#{attribute}_confirmation" })
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ # Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example:
17
+ #
18
+ # Model:
19
+ # class Person < ActiveRecord::Base
20
+ # validates_confirmation_of :user_name, :password
21
+ # validates_confirmation_of :email_address, :message => "should match confirmation"
22
+ # end
23
+ #
24
+ # View:
25
+ # <%= password_field "person", "password" %>
26
+ # <%= password_field "person", "password_confirmation" %>
27
+ #
28
+ # The added +password_confirmation+ attribute is virtual; it exists only as an in-memory attribute for validating the password.
29
+ # To achieve this, the validation adds accessors to the model for the confirmation attribute. NOTE: This check is performed
30
+ # only if +password_confirmation+ is not +nil+, and by default only on save. To require confirmation, make sure to add a presence
31
+ # check for the confirmation attribute:
32
+ #
33
+ # validates_presence_of :password_confirmation, :if => :password_changed?
34
+ #
35
+ # Configuration options:
36
+ # * <tt>:message</tt> - A custom error message (default is: "doesn't match confirmation").
37
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
38
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
39
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
40
+ # method, proc or string should return or evaluate to a true or false value.
41
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
42
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
43
+ # method, proc or string should return or evaluate to a true or false value.
44
+ def validates_confirmation_of(*attr_names)
45
+ validates_with ConfirmationValidator, _merge_attributes(attr_names)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,40 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class ExclusionValidator < EachValidator
4
+ def check_validity!
5
+ raise ArgumentError, "An object with the method include? is required must be supplied as the " <<
6
+ ":in option of the configuration hash" unless options[:in].respond_to?(:include?)
7
+ end
8
+
9
+ def validate_each(record, attribute, value)
10
+ return unless options[:in].include?(value)
11
+ record.errors.add(attribute, :exclusion, :default => options[:message], :value => value)
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ # Validates that the value of the specified attribute is not in a particular enumerable object.
17
+ #
18
+ # class Person < ActiveRecord::Base
19
+ # validates_exclusion_of :username, :in => %w( admin superuser ), :message => "You don't belong here"
20
+ # validates_exclusion_of :age, :in => 30..60, :message => "This site is only for under 30 and over 60"
21
+ # validates_exclusion_of :format, :in => %w( mov avi ), :message => "extension {{value}} is not allowed"
22
+ # end
23
+ #
24
+ # Configuration options:
25
+ # * <tt>:in</tt> - An enumerable object of items that the value shouldn't be part of.
26
+ # * <tt>:message</tt> - Specifies a custom error message (default is: "is reserved").
27
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
28
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
29
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
30
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
31
+ # method, proc or string should return or evaluate to a true or false value.
32
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
33
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
34
+ # method, proc or string should return or evaluate to a true or false value.
35
+ def validates_exclusion_of(*attr_names)
36
+ validates_with ExclusionValidator, _merge_attributes(attr_names)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,64 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class FormatValidator < EachValidator
4
+ def validate_each(record, attribute, value)
5
+ if options[:with] && value.to_s !~ options[:with]
6
+ record.errors.add(attribute, :invalid, :default => options[:message], :value => value)
7
+ elsif options[:without] && value.to_s =~ options[:without]
8
+ record.errors.add(attribute, :invalid, :default => options[:message], :value => value)
9
+ end
10
+ end
11
+
12
+ def check_validity!
13
+ unless options.include?(:with) ^ options.include?(:without) # ^ == xor, or "exclusive or"
14
+ raise ArgumentError, "Either :with or :without must be supplied (but not both)"
15
+ end
16
+
17
+ if options[:with] && !options[:with].is_a?(Regexp)
18
+ raise ArgumentError, "A regular expression must be supplied as the :with option of the configuration hash"
19
+ end
20
+
21
+ if options[:without] && !options[:without].is_a?(Regexp)
22
+ raise ArgumentError, "A regular expression must be supplied as the :without option of the configuration hash"
23
+ end
24
+ end
25
+ end
26
+
27
+ module ClassMethods
28
+ # Validates whether the value of the specified attribute is of the correct form, going by the regular expression provided.
29
+ # You can require that the attribute matches the regular expression:
30
+ #
31
+ # class Person < ActiveRecord::Base
32
+ # validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
33
+ # end
34
+ #
35
+ # Alternatively, you can require that the specified attribute does _not_ match the regular expression:
36
+ #
37
+ # class Person < ActiveRecord::Base
38
+ # validates_format_of :email, :without => /NOSPAM/
39
+ # end
40
+ #
41
+ # Note: use <tt>\A</tt> and <tt>\Z</tt> to match the start and end of the string, <tt>^</tt> and <tt>$</tt> match the start/end of a line.
42
+ #
43
+ # You must pass either <tt>:with</tt> or <tt>:without</tt> as an option. In addition, both must be a regular expression,
44
+ # or else an exception will be raised.
45
+ #
46
+ # Configuration options:
47
+ # * <tt>:message</tt> - A custom error message (default is: "is invalid").
48
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
49
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
50
+ # * <tt>:with</tt> - Regular expression that if the attribute matches will result in a successful validation.
51
+ # * <tt>:without</tt> - Regular expression that if the attribute does not match will result in a successful validation.
52
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
53
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
54
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
55
+ # method, proc or string should return or evaluate to a true or false value.
56
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
57
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
58
+ # method, proc or string should return or evaluate to a true or false value.
59
+ def validates_format_of(*attr_names)
60
+ validates_with FormatValidator, _merge_attributes(attr_names)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,40 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class InclusionValidator < EachValidator
4
+ def check_validity!
5
+ raise ArgumentError, "An object with the method include? is required must be supplied as the " <<
6
+ ":in option of the configuration hash" unless options[:in].respond_to?(:include?)
7
+ end
8
+
9
+ def validate_each(record, attribute, value)
10
+ return if options[:in].include?(value)
11
+ record.errors.add(attribute, :inclusion, :default => options[:message], :value => value)
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ # Validates whether the value of the specified attribute is available in a particular enumerable object.
17
+ #
18
+ # class Person < ActiveRecord::Base
19
+ # validates_inclusion_of :gender, :in => %w( m f )
20
+ # validates_inclusion_of :age, :in => 0..99
21
+ # validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension {{value}} is not included in the list"
22
+ # end
23
+ #
24
+ # Configuration options:
25
+ # * <tt>:in</tt> - An enumerable object of available items.
26
+ # * <tt>:message</tt> - Specifies a custom error message (default is: "is not included in the list").
27
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
28
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
29
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
30
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
31
+ # method, proc or string should return or evaluate to a true or false value.
32
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
33
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
34
+ # method, proc or string should return or evaluate to a true or false value.
35
+ def validates_inclusion_of(*attr_names)
36
+ validates_with InclusionValidator, _merge_attributes(attr_names)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,98 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class LengthValidator < EachValidator
4
+ MESSAGES = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }.freeze
5
+ CHECKS = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze
6
+
7
+ DEFAULT_TOKENIZER = lambda { |value| value.split(//) }
8
+
9
+ def initialize(options)
10
+ if range = (options.delete(:in) || options.delete(:within))
11
+ raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
12
+ options[:minimum], options[:maximum] = range.begin, range.end
13
+ options[:maximum] -= 1 if range.exclude_end?
14
+ end
15
+
16
+ super(options.reverse_merge(:tokenizer => DEFAULT_TOKENIZER))
17
+ end
18
+
19
+ def check_validity!
20
+ keys = CHECKS.keys & options.keys
21
+
22
+ if keys.empty?
23
+ raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
24
+ end
25
+
26
+ keys.each do |key|
27
+ value = options[key]
28
+
29
+ unless value.is_a?(Integer) && value >= 0
30
+ raise ArgumentError, ":#{key} must be a nonnegative Integer"
31
+ end
32
+ end
33
+ end
34
+
35
+ def validate_each(record, attribute, value)
36
+ value = options[:tokenizer].call(value) if value.kind_of?(String)
37
+
38
+ CHECKS.each do |key, validity_check|
39
+ next unless check_value = options[key]
40
+ custom_message = options[:message] || options[MESSAGES[key]]
41
+
42
+ valid_value = if key == :maximum
43
+ value.nil? || value.size.send(validity_check, check_value)
44
+ else
45
+ value && value.size.send(validity_check, check_value)
46
+ end
47
+
48
+ next if valid_value
49
+ record.errors.add(attribute, MESSAGES[key], :default => custom_message, :count => check_value)
50
+ end
51
+ end
52
+ end
53
+
54
+ module ClassMethods
55
+
56
+ # Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time:
57
+ #
58
+ # class Person < ActiveRecord::Base
59
+ # validates_length_of :first_name, :maximum=>30
60
+ # validates_length_of :last_name, :maximum=>30, :message=>"less than 30 if you don't mind"
61
+ # validates_length_of :fax, :in => 7..32, :allow_nil => true
62
+ # validates_length_of :phone, :in => 7..32, :allow_blank => true
63
+ # validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
64
+ # validates_length_of :zip_code, :minimum => 5, :too_short => "please enter at least 5 characters"
65
+ # validates_length_of :smurf_leader, :is => 4, :message => "papa is spelled with 4 characters... don't play me."
66
+ # validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least 100 words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
67
+ # end
68
+ #
69
+ # Configuration options:
70
+ # * <tt>:minimum</tt> - The minimum size of the attribute.
71
+ # * <tt>:maximum</tt> - The maximum size of the attribute.
72
+ # * <tt>:is</tt> - The exact size of the attribute.
73
+ # * <tt>:within</tt> - A range specifying the minimum and maximum size of the attribute.
74
+ # * <tt>:in</tt> - A synonym(or alias) for <tt>:within</tt>.
75
+ # * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation.
76
+ # * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
77
+ # * <tt>:too_long</tt> - The error message if the attribute goes over the maximum (default is: "is too long (maximum is {{count}} characters)").
78
+ # * <tt>:too_short</tt> - The error message if the attribute goes under the minimum (default is: "is too short (min is {{count}} characters)").
79
+ # * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt> method and the attribute is the wrong size (default is: "is the wrong length (should be {{count}} characters)").
80
+ # * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>, <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message.
81
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
82
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
83
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
84
+ # method, proc or string should return or evaluate to a true or false value.
85
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
86
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
87
+ # method, proc or string should return or evaluate to a true or false value.
88
+ # * <tt>:tokenizer</tt> - Specifies how to split up the attribute string. (e.g. <tt>:tokenizer => lambda {|str| str.scan(/\w+/)}</tt> to
89
+ # count words as in above example.)
90
+ # Defaults to <tt>lambda{ |value| value.split(//) }</tt> which counts individual characters.
91
+ def validates_length_of(*attr_names)
92
+ validates_with LengthValidator, _merge_attributes(attr_names)
93
+ end
94
+
95
+ alias_method :validates_size_of, :validates_length_of
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,111 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class NumericalityValidator < EachValidator
4
+ CHECKS = { :greater_than => :>, :greater_than_or_equal_to => :>=,
5
+ :equal_to => :==, :less_than => :<, :less_than_or_equal_to => :<=,
6
+ :odd => :odd?, :even => :even? }.freeze
7
+
8
+ def initialize(options)
9
+ super(options.reverse_merge(:only_integer => false, :allow_nil => false))
10
+ end
11
+
12
+ def check_validity!
13
+ keys = CHECKS.keys - [:odd, :even]
14
+ options.slice(*keys).each do |option, value|
15
+ next if value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
16
+ raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
17
+ end
18
+ end
19
+
20
+ def validate_each(record, attr_name, value)
21
+ before_type_cast = "#{attr_name}_before_type_cast"
22
+
23
+ raw_value = record.send("#{attr_name}_before_type_cast") if record.respond_to?(before_type_cast.to_sym)
24
+ raw_value ||= value
25
+
26
+ return if options[:allow_nil] && raw_value.nil?
27
+
28
+ unless value = parse_raw_value(raw_value, options)
29
+ record.errors.add(attr_name, :not_a_number, :value => raw_value, :default => options[:message])
30
+ return
31
+ end
32
+
33
+ options.slice(*CHECKS.keys).each do |option, option_value|
34
+ case option
35
+ when :odd, :even
36
+ unless value.to_i.send(CHECKS[option])
37
+ record.errors.add(attr_name, option, :value => value, :default => options[:message])
38
+ end
39
+ else
40
+ option_value = option_value.call(record) if option_value.is_a?(Proc)
41
+ option_value = record.send(option_value) if option_value.is_a?(Symbol)
42
+
43
+ unless value.send(CHECKS[option], option_value)
44
+ record.errors.add(attr_name, option, :default => options[:message], :value => value, :count => option_value)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ protected
51
+
52
+ def parse_raw_value(raw_value, options)
53
+ if options[:only_integer]
54
+ raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/
55
+ else
56
+ begin
57
+ Kernel.Float(raw_value)
58
+ rescue ArgumentError, TypeError
59
+ nil
60
+ end
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ module ClassMethods
67
+ # Validates whether the value of the specified attribute is numeric by trying to convert it to
68
+ # a float with Kernel.Float (if <tt>only_integer</tt> is false) or applying it to the regular expression
69
+ # <tt>/\A[\+\-]?\d+\Z/</tt> (if <tt>only_integer</tt> is set to true).
70
+ #
71
+ # class Person < ActiveRecord::Base
72
+ # validates_numericality_of :value, :on => :create
73
+ # end
74
+ #
75
+ # Configuration options:
76
+ # * <tt>:message</tt> - A custom error message (default is: "is not a number").
77
+ # * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
78
+ # * <tt>:only_integer</tt> - Specifies whether the value has to be an integer, e.g. an integral value (default is +false+).
79
+ # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is +false+). Notice that for fixnum and float columns empty strings are converted to +nil+.
80
+ # * <tt>:greater_than</tt> - Specifies the value must be greater than the supplied value.
81
+ # * <tt>:greater_than_or_equal_to</tt> - Specifies the value must be greater than or equal the supplied value.
82
+ # * <tt>:equal_to</tt> - Specifies the value must be equal to the supplied value.
83
+ # * <tt>:less_than</tt> - Specifies the value must be less than the supplied value.
84
+ # * <tt>:less_than_or_equal_to</tt> - Specifies the value must be less than or equal the supplied value.
85
+ # * <tt>:odd</tt> - Specifies the value must be an odd number.
86
+ # * <tt>:even</tt> - Specifies the value must be an even number.
87
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
88
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
89
+ # method, proc or string should return or evaluate to a true or false value.
90
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
91
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
92
+ # method, proc or string should return or evaluate to a true or false value.
93
+ #
94
+ # The following checks can also be supplied with a proc or a symbol which corresponds to a method:
95
+ # * <tt>:greater_than</tt>
96
+ # * <tt>:greater_than_or_equal_to</tt>
97
+ # * <tt>:equal_to</tt>
98
+ # * <tt>:less_than</tt>
99
+ # * <tt>:less_than_or_equal_to</tt>
100
+ #
101
+ # class Person < ActiveRecord::Base
102
+ # validates_numericality_of :width, :less_than => Proc.new { |person| person.height }
103
+ # validates_numericality_of :width, :greater_than => :minimum_weight
104
+ # end
105
+ #
106
+ def validates_numericality_of(*attr_names)
107
+ validates_with NumericalityValidator, _merge_attributes(attr_names)
108
+ end
109
+ end
110
+ end
111
+ end