From 4d9126cfccefdb69149caf7681d674b50335e9b4 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sun, 11 Mar 2018 18:19:20 +0000 Subject: Apply time column precision on assignment In #20317, datetime columns had their precision applied on assignment but that behaviour wasn't applied to time columns - this commit fixes that. Fixes #30301. --- activemodel/lib/active_model/type/time.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activemodel/lib') diff --git a/activemodel/lib/active_model/type/time.rb b/activemodel/lib/active_model/type/time.rb index ad7ba0351a..8e939ac00a 100644 --- a/activemodel/lib/active_model/type/time.rb +++ b/activemodel/lib/active_model/type/time.rb @@ -28,7 +28,7 @@ module ActiveModel private def cast_value(value) - return value unless value.is_a?(::String) + return apply_seconds_precision(value) unless value.is_a?(::String) return if value.empty? if value.start_with?("2000-01-01") -- cgit v1.2.3 From 3f95054f1c5ffe9e9b3bccdabc1ab1a7a4beb24a Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sun, 11 Mar 2018 18:23:50 +0000 Subject: Normalize date component when writing to time columns For legacy reasons Rails stores time columns on sqlite as full timestamp strings. However because the date component wasn't being normalized this meant that when they were read back they were being prefixed with 2001-01-01 by ActiveModel::Type::Time. This had a twofold result - first it meant that the fast code path wasn't being used because the string was invalid and second it was corrupting the second fractional component being read by the Date._parse code path. Fix this by a combination of normalizing the timestamps on writing and also changing Active Model to be more lenient when detecting whether a string starts with a date component before creating the dummy time value for parsing. --- activemodel/lib/active_model/type/time.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'activemodel/lib') diff --git a/activemodel/lib/active_model/type/time.rb b/activemodel/lib/active_model/type/time.rb index 8e939ac00a..c094ee0013 100644 --- a/activemodel/lib/active_model/type/time.rb +++ b/activemodel/lib/active_model/type/time.rb @@ -31,11 +31,7 @@ module ActiveModel return apply_seconds_precision(value) unless value.is_a?(::String) return if value.empty? - if value.start_with?("2000-01-01") - dummy_time_value = value - else - dummy_time_value = "2000-01-01 #{value}" - end + dummy_time_value = value.sub(/\A(\d\d\d\d-\d\d-\d\d |)/, "2000-01-01 ") fast_string_to_time(dummy_time_value) || begin time_hash = ::Date._parse(dummy_time_value) -- cgit v1.2.3