diff options
author | Yves Senn <yves.senn@gmail.com> | 2014-08-04 13:09:13 +0200 |
---|---|---|
committer | Yves Senn <yves.senn@gmail.com> | 2014-08-04 13:09:13 +0200 |
commit | b2e88043b52a8f83820a0f4e8a65aa42fd40c544 (patch) | |
tree | ae1d5d749e2f38e7e56d6b4c50b238cdd59846cb | |
parent | 3d70f0740b26b0a137d7e6436f9909330f8ee888 (diff) | |
parent | 1d6a87779c73bc7d9d5f235afadc0df4a36f534f (diff) | |
download | rails-b2e88043b52a8f83820a0f4e8a65aa42fd40c544.tar.gz rails-b2e88043b52a8f83820a0f4e8a65aa42fd40c544.tar.bz2 rails-b2e88043b52a8f83820a0f4e8a65aa42fd40c544.zip |
Merge pull request #16333 from joker1007/fix_decimal_cast_from_float_with_large_precision
Fix type casting to Decimal from Float with large precision
Conflicts:
activerecord/CHANGELOG.md
-rw-r--r-- | activerecord/CHANGELOG.md | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/decimal.rb | 21 | ||||
-rw-r--r-- | activerecord/test/cases/type/decimal_test.rb | 5 |
3 files changed, 26 insertions, 4 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 5988ded344..9043542fda 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* Fix type casting to Decimal from Float with large precision. + + *Tomohiro Hashidate* + * Deprecate `Reflection#source_macro` `Reflection#source_macro` is no longer needed in Active Record diff --git a/activerecord/lib/active_record/type/decimal.rb b/activerecord/lib/active_record/type/decimal.rb index ba5d244729..d10778eeb6 100644 --- a/activerecord/lib/active_record/type/decimal.rb +++ b/activerecord/lib/active_record/type/decimal.rb @@ -14,12 +14,25 @@ module ActiveRecord private def cast_value(value) - if value.is_a?(::Numeric) || value.is_a?(::String) + case value + when ::Float + BigDecimal(value, float_precision) + when ::Numeric, ::String BigDecimal(value, precision.to_i) - elsif value.respond_to?(:to_d) - value.to_d else - cast_value(value.to_s) + if value.respond_to?(:to_d) + value.to_d + else + cast_value(value.to_s) + end + end + end + + def float_precision + if precision.to_i > ::Float::DIG + 1 + ::Float::DIG + 1 + else + precision.to_i end end end diff --git a/activerecord/test/cases/type/decimal_test.rb b/activerecord/test/cases/type/decimal_test.rb index 951cd879dd..da30de373e 100644 --- a/activerecord/test/cases/type/decimal_test.rb +++ b/activerecord/test/cases/type/decimal_test.rb @@ -10,6 +10,11 @@ module ActiveRecord assert_equal BigDecimal.new("1"), type.type_cast_from_user(:"1") end + def test_type_cast_decimal_from_float_with_large_precision + type = Decimal.new(precision: ::Float::DIG + 2) + assert_equal BigDecimal.new("123.0"), type.type_cast_from_user(123.0) + 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)) |