From b96fdd234de9484b6c0999d04193de31d925dc3a Mon Sep 17 00:00:00 2001
From: Robert Eshleman <c.robert.eshleman@gmail.com>
Date: Tue, 22 Dec 2015 12:23:33 -0500
Subject: Failing Tests for Validating String Numbericality

Covers Regressions:

* <=
* <
* ==
* >
* >=
* other than
---
 .../validations/numericality_validation_test.rb    | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/activemodel/test/cases/validations/numericality_validation_test.rb b/activemodel/test/cases/validations/numericality_validation_test.rb
index 04ec74bad3..74a048537d 100644
--- a/activemodel/test/cases/validations/numericality_validation_test.rb
+++ b/activemodel/test/cases/validations/numericality_validation_test.rb
@@ -79,6 +79,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
     valid!([97.18, 98, BigDecimal.new('98')]) # Notice the 97.18 as a float is greater than 97.18 as a BigDecimal due to floating point precision
   end
 
+  def test_validates_numericality_with_greater_than_using_string_value
+    Topic.validates_numericality_of :approved, greater_than: 10
+
+    invalid!(['-10', '9', '9.9', '10'], 'must be greater than 10')
+    valid!(['10.1', '11'])
+  end
+
   def test_validates_numericality_with_greater_than_or_equal
     Topic.validates_numericality_of :approved, greater_than_or_equal_to: 10
 
@@ -93,6 +100,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
     valid!([97.18, 98, BigDecimal.new('97.19')])
   end
 
+  def test_validates_numericality_with_greater_than_or_equal_using_string_value
+    Topic.validates_numericality_of :approved, greater_than_or_equal_to: 10
+
+    invalid!(['-10', '9', '9.9'], 'must be greater than or equal to 10')
+    valid!(['10', '10.1', '11'])
+  end
+
   def test_validates_numericality_with_equal_to
     Topic.validates_numericality_of :approved, equal_to: 10
 
@@ -107,6 +121,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
     valid!([BigDecimal.new('97.18')])
   end
 
+  def test_validates_numericality_with_equal_to_using_string_value
+    Topic.validates_numericality_of :approved, equal_to: 10
+
+    invalid!(['-10', '9', '9.9', '10.1', '11'], 'must be equal to 10')
+    valid!(['10'])
+  end
+
   def test_validates_numericality_with_less_than
     Topic.validates_numericality_of :approved, less_than: 10
 
@@ -121,6 +142,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
     valid!([-97.0, 97.0, -97, 97, BigDecimal.new('-97'), BigDecimal.new('97')])
   end
 
+  def test_validates_numericality_with_less_than_using_string_value
+    Topic.validates_numericality_of :approved, less_than: 10
+
+    invalid!(['10', '10.1', '11'], 'must be less than 10')
+    valid!(['-10', '9', '9.9'])
+  end
+
   def test_validates_numericality_with_less_than_or_equal_to
     Topic.validates_numericality_of :approved, less_than_or_equal_to: 10
 
@@ -135,6 +163,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
     valid!([-97.18, BigDecimal.new('-97.18'), BigDecimal.new('97.18')])
   end
 
+  def test_validates_numericality_with_less_than_or_equal_using_string_value
+    Topic.validates_numericality_of :approved, less_than_or_equal_to: 10
+
+    invalid!(['10.1', '11'], 'must be less than or equal to 10')
+    valid!(['-10', '9', '9.9', '10'])
+  end
+
   def test_validates_numericality_with_odd
     Topic.validates_numericality_of :approved, odd: true
 
@@ -163,6 +198,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
     valid!([-1, 42])
   end
 
+  def test_validates_numericality_with_other_than_using_string_value
+    Topic.validates_numericality_of :approved, other_than: 0
+
+    invalid!(['0', '0.0'])
+    valid!(['-1', '1.1', '42'])
+  end
+
   def test_validates_numericality_with_proc
     Topic.send(:define_method, :min_approved, lambda { 5 })
     Topic.validates_numericality_of :approved, greater_than_or_equal_to: Proc.new(&:min_approved)
-- 
cgit v1.2.3


From 9c330798b0a77762b72a833519e10b01738cf79c Mon Sep 17 00:00:00 2001
From: Robert Eshleman <c.robert.eshleman@gmail.com>
Date: Tue, 22 Dec 2015 13:29:54 -0500
Subject: Fix Regression in Numericality Validations

A regression (#22744) introduced in 7500dae caused certain numericality
validations to raise an error when run against an attribute with a
string value. Previously, these validations would successfully run
against string values because the value was cast to a numeric class.

This commit resolves the regression by converting string values to
floats before performing numericality comparison validations.

[fixes #22744]
---
 activemodel/lib/active_model/validations/numericality.rb | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index 9c1e8b4ba7..176a111bcc 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -39,6 +39,10 @@ module ActiveModel
           return
         end
 
+        if raw_value.is_a?(String)
+          value = parse_raw_value_as_a_number(raw_value)
+        end
+
         options.slice(*CHECKS.keys).each do |option, option_value|
           case option
           when :odd, :even
@@ -63,12 +67,15 @@ module ActiveModel
     protected
 
       def is_number?(raw_value)
-        parsed_value = Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
-        !parsed_value.nil?
+        !parse_raw_value_as_a_number(raw_value).nil?
       rescue ArgumentError, TypeError
         false
       end
 
+      def parse_raw_value_as_a_number(raw_value)
+        Kernel.Float(raw_value) if raw_value !~ /\A0[xX]/
+      end
+
       def is_integer?(raw_value)
         /\A[+-]?\d+\z/ === raw_value.to_s
       end
-- 
cgit v1.2.3


From 57fb74e081005806f729cb7b03320f050fa6e67b Mon Sep 17 00:00:00 2001
From: Robert Eshleman <c.robert.eshleman@gmail.com>
Date: Tue, 22 Dec 2015 16:01:50 -0500
Subject: Convert non-`Numeric` values to Floats

---
 activemodel/lib/active_model/validations/numericality.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index 176a111bcc..ad7012df48 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -39,7 +39,7 @@ module ActiveModel
           return
         end
 
-        if raw_value.is_a?(String)
+        unless raw_value.is_a?(Numeric)
           value = parse_raw_value_as_a_number(raw_value)
         end
 
-- 
cgit v1.2.3