From 7c67b949869366bf82805f42e38a0bb1757eaadc Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Mon, 22 Mar 2021 15:20:50 +0900 Subject: [PATCH] Make infinity handling symmetrical in cast and deserialize Related: #41716, 30391e9ddba745d6bdc0b23f526ecf432dfe6adf. --- .../active_record/attribute_methods/time_zone_conversion.rb | 6 +++--- .../test/cases/adapters/postgresql/infinity_test.rb | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb index 0423c7bf06..3eed7afd3e 100644 --- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb +++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -19,14 +19,14 @@ def cast(value) if value.is_a?(Hash) set_time_zone_without_conversion(super) - elsif value == ::Float::INFINITY || value == -::Float::INFINITY - value elsif value.respond_to?(:in_time_zone) begin super(user_input_in_time_zone(value)) || super rescue ArgumentError nil end + elsif value.respond_to?(:infinite?) && value.infinite? + value else map_avoiding_infinite_recursion(super) { |v| cast(v) } end @@ -38,7 +38,7 @@ def convert_time_to_time_zone(value) if value.acts_like?(:time) value.in_time_zone - elsif value.is_a?(::Float) + elsif value.respond_to?(:infinite?) && value.infinite? value else map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) } diff --git a/activerecord/test/cases/adapters/postgresql/infinity_test.rb b/activerecord/test/cases/adapters/postgresql/infinity_test.rb index 968c016d47..d599683f2a 100644 --- a/activerecord/test/cases/adapters/postgresql/infinity_test.rb +++ b/activerecord/test/cases/adapters/postgresql/infinity_test.rb @@ -82,6 +82,10 @@ class PostgresqlInfinity < ActiveRecord::Base record = PostgresqlInfinity.create!(datetime: Float::INFINITY) assert_equal Float::INFINITY, record.datetime assert_equal record.datetime, record.reload.datetime + + record = PostgresqlInfinity.create!(datetime: BigDecimal::INFINITY) + assert_equal Float::INFINITY, record.datetime + assert_equal record.datetime, record.reload.datetime end ensure # setting time_zone_aware_attributes causes the types to change.