mirror of https://github.com/rails/rails
Fix dirty check for Float::NaN and BigDecimal::NaN
Float::NaN and BigDecimal::NaN in Ruby are [special values](https://bugs.ruby-lang.org/issues/1720) and can't be compared with `==`.
This commit is contained in:
parent
5d78c54a46
commit
d1df4c100f
|
@ -1,3 +1,10 @@
|
|||
* Fix dirty check for Float::NaN and BigDecimal::NaN.
|
||||
|
||||
Float::NaN and BigDecimal::NaN in Ruby are [special values](https://bugs.ruby-lang.org/issues/1720)
|
||||
and can't be compared with `==`.
|
||||
|
||||
*Marcelo Lauxen*
|
||||
|
||||
* Fix `to_json` for `ActiveModel::Dirty` object.
|
||||
|
||||
Exclude `mutations_from_database` attribute from json as it lead to recursion.
|
||||
|
|
|
@ -25,10 +25,18 @@ module ActiveModel
|
|||
end
|
||||
|
||||
def changed?(old_value, _new_value, new_value_before_type_cast) # :nodoc:
|
||||
super || number_to_non_number?(old_value, new_value_before_type_cast)
|
||||
(super || number_to_non_number?(old_value, new_value_before_type_cast)) &&
|
||||
!equal_nan?(old_value, new_value_before_type_cast)
|
||||
end
|
||||
|
||||
private
|
||||
def equal_nan?(old_value, new_value)
|
||||
(old_value.is_a?(::Float) || old_value.is_a?(BigDecimal)) &&
|
||||
old_value.nan? &&
|
||||
old_value.instance_of?(new_value.class) &&
|
||||
new_value.nan?
|
||||
end
|
||||
|
||||
def number_to_non_number?(old_value, new_value_before_type_cast)
|
||||
old_value != nil && non_numeric_string?(new_value_before_type_cast.to_s)
|
||||
end
|
||||
|
|
|
@ -66,6 +66,8 @@ module ActiveModel
|
|||
assert_not type.changed?(5.0, 5.0, "5.0")
|
||||
assert_not type.changed?(-5.0, -5.0, "-5.0")
|
||||
assert_not type.changed?(5.0, 5.0, "0.5e+1")
|
||||
assert_not type.changed?(BigDecimal("0.0") / 0, BigDecimal("0.0") / 0, BigDecimal("0.0") / 0)
|
||||
assert type.changed?(BigDecimal("0.0") / 0, 0.0 / 0.0, 0.0 / 0.0)
|
||||
end
|
||||
|
||||
def test_scale_is_applied_before_precision_to_prevent_rounding_errors
|
||||
|
|
|
@ -28,6 +28,8 @@ module ActiveModel
|
|||
assert_not type.changed?(5.0, 5.0, "5.0")
|
||||
assert_not type.changed?(500.0, 500.0, "0.5E+4")
|
||||
assert_not type.changed?(nil, nil, nil)
|
||||
assert_not type.changed?(0.0 / 0.0, 0.0 / 0.0, 0.0 / 0.0)
|
||||
assert type.changed?(0.0 / 0.0, BigDecimal("0.0") / 0, BigDecimal("0.0") / 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue