aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model
diff options
context:
space:
mode:
authorJohn Hawthorn <john@stembolt.com>2016-12-21 15:33:37 -0800
committerRafael Mendonça França <rafaelmfranca@gmail.com>2017-02-24 19:41:23 -0500
commit68926798a53bb98e56efe9a96e321a33cc0fa995 (patch)
tree1a501f88900d3a3cf214b68764d3329294cf7515 /activemodel/lib/active_model
parentfeea081199f1398e7fa97bf22eb6081ecd2d6174 (diff)
downloadrails-68926798a53bb98e56efe9a96e321a33cc0fa995.tar.gz
rails-68926798a53bb98e56efe9a96e321a33cc0fa995.tar.bz2
rails-68926798a53bb98e56efe9a96e321a33cc0fa995.zip
Fix invalid string Decimal casting under ruby 2.4
In Ruby 2.4, BigDecimal(), as used by the Decimal cast, was changed so that it will raise ArgumentError when passed an invalid string, in order to be more consistent with Integer(), Float(), etc. The other numeric types use ex. to_i and to_f. Unfortunately, we can't simply change BigDecimal() to to_d. String#to_d raises errors like BigDecimal(), unlike all the other to_* methods (this should probably be filed as a ruby bug). Instead, this simulates the existing behaviour and the behaviour of the other to_* methods by finding a numeric string at the start of the passed in value, and parsing that using BigDecimal(). See also https://bugs.ruby-lang.org/issues/10286 https://github.com/ruby/bigdecimal/commit/3081a627cebdc1fc119425c7a9f009dbb6bec8e8
Diffstat (limited to 'activemodel/lib/active_model')
-rw-r--r--activemodel/lib/active_model/type/decimal.rb4
1 files changed, 3 insertions, 1 deletions
diff --git a/activemodel/lib/active_model/type/decimal.rb b/activemodel/lib/active_model/type/decimal.rb
index 541a12c8a1..b4ba8d4b1f 100644
--- a/activemodel/lib/active_model/type/decimal.rb
+++ b/activemodel/lib/active_model/type/decimal.rb
@@ -21,8 +21,10 @@ module ActiveModel
case value
when ::Float
convert_float_to_big_decimal(value)
- when ::Numeric, ::String
+ when ::Numeric
BigDecimal(value, precision || BIGDECIMAL_PRECISION)
+ when ::String
+ value.to_d rescue BigDecimal(0)
else
if value.respond_to?(:to_d)
value.to_d