Skip to content
This repository
Browse code

Fix bug when Column is trying to type cast boolean values to integer.

This can occur if the user is using :integer columns to store boolean
values. Now we are handling the boolean values but it still raises if
the value can't type cast to integer and is not a boolean. See #7509.

Fixes #8067.
  • Loading branch information...
commit 96a13fc7de77d7e5cdadb2857b94c4e859174faa 1 parent e6b4184
Rafael Mendonça França authored October 29, 2012
5  activerecord/CHANGELOG.md
Source Rendered
... ...
@@ -1,5 +1,10 @@
1 1
 ## Rails 3.2.9 (unreleased)
2 2
 
  3
+*   Fix bug when Column is trying to type cast boolean values to integer.
  4
+    Fixes #8067.
  5
+
  6
+    *Rafael Mendonça França*
  7
+
3 8
 *   Fixed support for DATABASE_URL environment variable for rake db tasks. *Grace Liu*
4 9
 
5 10
 *   Fix bug where `update_columns` and `update_column` would not let you update the primary key column.
15  activerecord/lib/active_record/connection_adapters/column.rb
@@ -75,7 +75,7 @@ def type_cast(value)
75 75
 
76 76
         case type
77 77
         when :string, :text        then value
78  
-        when :integer              then value.to_i
  78
+        when :integer              then klass.value_to_integer(value)
79 79
         when :float                then value.to_f
80 80
         when :decimal              then klass.value_to_decimal(value)
81 81
         when :datetime, :timestamp then klass.string_to_time(value)
@@ -92,7 +92,7 @@ def type_cast_code(var_name)
92 92
 
93 93
         case type
94 94
         when :string, :text        then var_name
95  
-        when :integer              then "(#{var_name}.to_i)"
  95
+        when :integer              then "#{klass}.value_to_integer(#{var_name})"
96 96
         when :float                then "#{var_name}.to_f"
97 97
         when :decimal              then "#{klass}.value_to_decimal(#{var_name})"
98 98
         when :datetime, :timestamp then "#{klass}.string_to_time(#{var_name})"
@@ -168,6 +168,17 @@ def value_to_boolean(value)
168 168
           end
169 169
         end
170 170
 
  171
+        # Used to convert values to integer.
  172
+        # handle the case when an integer column is used to store bollean values
  173
+        def value_to_integer(value)
  174
+          case value
  175
+          when TrueClass, FalseClass
  176
+            value ? 1 : 0
  177
+          else
  178
+            value.to_i
  179
+          end
  180
+        end
  181
+
171 182
         # convert something to a BigDecimal
172 183
         def value_to_decimal(value)
173 184
           # Using .class is faster than .is_a? and
8  activerecord/test/cases/column_test.rb
@@ -33,6 +33,8 @@ def test_type_cast_integer
33 33
         assert_equal 0, column.type_cast('bad1')
34 34
         assert_equal 0, column.type_cast('bad')
35 35
         assert_equal 1, column.type_cast(1.7)
  36
+        assert_equal 0, column.type_cast(false)
  37
+        assert_equal 1, column.type_cast(true)
36 38
         assert_nil column.type_cast(nil)
37 39
       end
38 40
 
@@ -41,11 +43,9 @@ def test_type_cast_non_integer_to_integer
41 43
         assert_raises(NoMethodError) do
42 44
           column.type_cast([])
43 45
         end
  46
+
44 47
         assert_raises(NoMethodError) do
45  
-          column.type_cast(true)
46  
-        end
47  
-        assert_raises(NoMethodError) do
48  
-          column.type_cast(false)
  48
+          column.type_cast(Object.new)
49 49
         end
50 50
       end
51 51
     end
Something went wrong with that request. Please try again.