diff options
-rw-r--r-- | activerecord/lib/active_record/type/decimal.rb | 7 | ||||
-rw-r--r-- | activerecord/test/cases/type/decimal_test.rb | 33 | ||||
-rw-r--r-- | activerecord/test/cases/types_test.rb | 7 |
3 files changed, 38 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/type/decimal.rb b/activerecord/lib/active_record/type/decimal.rb index a9db51c6ba..27566cf856 100644 --- a/activerecord/lib/active_record/type/decimal.rb +++ b/activerecord/lib/active_record/type/decimal.rb @@ -14,10 +14,13 @@ module ActiveRecord private def cast_value(value) - if value.respond_to?(:to_d) + case value + when ::Numeric, ::String + BigDecimal(value, precision.to_i) + when proc { value.respond_to?(:to_d) } value.to_d else - value.to_s.to_d + cast_value(value.to_s) end end end diff --git a/activerecord/test/cases/type/decimal_test.rb b/activerecord/test/cases/type/decimal_test.rb new file mode 100644 index 0000000000..951cd879dd --- /dev/null +++ b/activerecord/test/cases/type/decimal_test.rb @@ -0,0 +1,33 @@ +require "cases/helper" + +module ActiveRecord + module Type + class DecimalTest < ActiveRecord::TestCase + def test_type_cast_decimal + type = Decimal.new + assert_equal BigDecimal.new("0"), type.type_cast_from_user(BigDecimal.new("0")) + assert_equal BigDecimal.new("123"), type.type_cast_from_user(123.0) + assert_equal BigDecimal.new("1"), type.type_cast_from_user(:"1") + end + + def test_type_cast_decimal_from_rational_with_precision + type = Decimal.new(precision: 2) + assert_equal BigDecimal("0.33"), type.type_cast_from_user(Rational(1, 3)) + end + + def test_type_cast_decimal_from_rational_without_precision_defaults_to_18_36 + type = Decimal.new + assert_equal BigDecimal("0.333333333333333333E0"), type.type_cast_from_user(Rational(1, 3)) + end + + def test_type_cast_decimal_from_object_responding_to_d + value = Object.new + def value.to_d + BigDecimal.new("1") + end + type = Decimal.new + assert_equal BigDecimal("1"), type.type_cast_from_user(value) + end + end + end +end diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb index 47cf775cb6..5c54812f30 100644 --- a/activerecord/test/cases/types_test.rb +++ b/activerecord/test/cases/types_test.rb @@ -95,13 +95,6 @@ module ActiveRecord assert_not type.changed?(nil, nil, nil) end - def test_type_cast_decimal - type = Type::Decimal.new - assert_equal BigDecimal.new("0"), type.type_cast_from_user(BigDecimal.new("0")) - assert_equal BigDecimal.new("123"), type.type_cast_from_user(123.0) - assert_equal BigDecimal.new("1"), type.type_cast_from_user(:"1") - end - def test_type_cast_binary type = Type::Binary.new assert_equal nil, type.type_cast_from_user(nil) |