Skip to content
This repository
Browse code

added proc and symbol support to validates_numericality_of [#3049 sta…

…te:resolved]

Signed-off-by: Joshua Peek <josh@joshpeek.com>
  • Loading branch information...
commit cf9f361699d72b5b34a655f8940c024cba0f0e09 1 parent 7e3abbf
authored August 31, 2009 josh committed August 31, 2009
21  activemodel/lib/active_model/validations/numericality.rb
@@ -31,6 +31,21 @@ module ClassMethods
31 31
       # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
32 32
       #   not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).  The
33 33
       #   method, proc or string should return or evaluate to a true or false value.
  34
+      #
  35
+      # The following checks can also be supplied with a proc or a symbol which corresponds to a method:
  36
+      # * <tt>:greater_than</tt>
  37
+      # * <tt>:greater_than_or_equal_to</tt>
  38
+      # * <tt>:equal_to</tt>
  39
+      # * <tt>:less_than</tt>
  40
+      # * <tt>:less_than_or_equal_to</tt>
  41
+      #
  42
+      #   class Person < ActiveRecord::Base
  43
+      #     validates_numericality_of :width, :less_than => Proc.new { |person| person.height }
  44
+      #     validates_numericality_of :width, :greater_than => :minimum_weight
  45
+      #   end
  46
+      #
  47
+      #
  48
+
34 49
       def validates_numericality_of(*attr_names)
35 50
         configuration = { :only_integer => false, :allow_nil => false }
36 51
         configuration.update(attr_names.extract_options!)
@@ -38,7 +53,8 @@ def validates_numericality_of(*attr_names)
38 53
         numericality_options = ALL_NUMERICALITY_CHECKS.keys & configuration.keys
39 54
 
40 55
         (numericality_options - [ :odd, :even ]).each do |option|
41  
-          raise ArgumentError, ":#{option} must be a number" unless configuration[option].is_a?(Numeric)
  56
+          value = configuration[option]
  57
+          raise ArgumentError, ":#{option} must be a number, a symbol or a proc" unless value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
42 58
         end
43 59
 
44 60
         validates_each(attr_names,configuration) do |record, attr_name, value|
@@ -74,6 +90,9 @@ def validates_numericality_of(*attr_names)
74 90
                 record.errors.add(attr_name, option, :value => raw_value, :default => configuration[:message])
75 91
               end
76 92
             else
  93
+              configuration[option] = configuration[option].call(record)        if configuration[option].is_a? Proc
  94
+              configuration[option] = record.method(configuration[option]).call if configuration[option].is_a? Symbol
  95
+              
77 96
               unless raw_value.method(ALL_NUMERICALITY_CHECKS[option])[configuration[option]]
78 97
                 record.errors.add(attr_name, option, :default => configuration[:message], :value => raw_value, :count => configuration[option])
79 98
               end
18  activemodel/test/cases/validations/numericality_validation_test.rb
@@ -106,6 +106,24 @@ def test_validates_numericality_with_greater_than_less_than_and_even
106 106
     valid!([2])
107 107
   end
108 108
 
  109
+  def test_validates_numericality_with_proc
  110
+    Topic.send(:define_method, :min_approved, lambda { 5 })
  111
+    Topic.validates_numericality_of :approved, :greater_than_or_equal_to => Proc.new {|topic| topic.min_approved }
  112
+
  113
+    invalid!([3, 4])
  114
+    valid!([5, 6])
  115
+    Topic.send(:remove_method, :min_approved)
  116
+  end
  117
+
  118
+  def test_validates_numericality_with_symbol
  119
+    Topic.send(:define_method, :max_approved, lambda { 5 })
  120
+    Topic.validates_numericality_of :approved, :less_than_or_equal_to => :max_approved
  121
+
  122
+    invalid!([6])
  123
+    valid!([4, 5])
  124
+    Topic.send(:remove_method, :max_approved)
  125
+  end
  126
+
109 127
   def test_validates_numericality_with_numeric_message
110 128
     Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than {{count}}"
111 129
     topic = Topic.new("title" => "numeric test", "approved" => 10)

0 notes on commit cf9f361

Please sign in to comment.
Something went wrong with that request. Please try again.