diff options
author | Bogdan Gusiev <agresso@gmail.com> | 2015-09-22 12:48:50 +0300 |
---|---|---|
committer | Bogdan Gusiev <agresso@gmail.com> | 2015-09-23 13:29:08 +0300 |
commit | d03f5196657bf466d7576cd6cbd4886db030723b (patch) | |
tree | 29b1c6b120ebe89878905c0b112892d5300f6585 /activemodel/lib | |
parent | 8842ce239562d3fbc82198ac3c4618935134ff39 (diff) | |
download | rails-d03f5196657bf466d7576cd6cbd4886db030723b.tar.gz rails-d03f5196657bf466d7576cd6cbd4886db030723b.tar.bz2 rails-d03f5196657bf466d7576cd6cbd4886db030723b.zip |
Fixed taking precision into count when assigning a value to timestamp attribute
Timestamp column can have less precision than ruby timestamp
In result in how big a fraction of a second can be stored in the
database.
m = Model.create!
m.created_at.usec == m.reload.created_at.usec
# => false
# due to different seconds precision in Time.now and database column
If the precision is low enough, (mysql default is 0, so it is always low
enough by default) the value changes when model is reloaded from the
database. This patch fixes that issue ensuring that any timestamp
assigned as an attribute is converted to column precision under the
attribute.
Diffstat (limited to 'activemodel/lib')
-rw-r--r-- | activemodel/lib/active_model/type/date_time.rb | 8 | ||||
-rw-r--r-- | activemodel/lib/active_model/type/helpers/time_value.rb | 13 |
2 files changed, 12 insertions, 9 deletions
diff --git a/activemodel/lib/active_model/type/date_time.rb b/activemodel/lib/active_model/type/date_time.rb index b068cfc672..2f2df4320f 100644 --- a/activemodel/lib/active_model/type/date_time.rb +++ b/activemodel/lib/active_model/type/date_time.rb @@ -12,11 +12,11 @@ module ActiveModel private - def cast_value(string) - return string unless string.is_a?(::String) - return if string.empty? + def cast_value(value) + return apply_seconds_precision(value) unless value.is_a?(::String) + return if value.empty? - fast_string_to_time(string) || fallback_string_to_time(string) + fast_string_to_time(value) || fallback_string_to_time(value) end # '0.123456' -> 123456 diff --git a/activemodel/lib/active_model/type/helpers/time_value.rb b/activemodel/lib/active_model/type/helpers/time_value.rb index 0a0e58654b..63993c0d93 100644 --- a/activemodel/lib/active_model/type/helpers/time_value.rb +++ b/activemodel/lib/active_model/type/helpers/time_value.rb @@ -5,11 +5,7 @@ module ActiveModel module Helpers module TimeValue # :nodoc: def serialize(value) - if precision && value.respond_to?(:usec) - number_of_insignificant_digits = 6 - precision - round_power = 10 ** number_of_insignificant_digits - value = value.change(usec: value.usec / round_power * round_power) - end + value = apply_seconds_precision(value) if value.acts_like?(:time) zone_conversion_method = is_utc? ? :getutc : :getlocal @@ -34,6 +30,13 @@ module ActiveModel end end + def apply_seconds_precision(value) + return value unless precision && value.respond_to?(:usec) + number_of_insignificant_digits = 6 - precision + round_power = 10 ** number_of_insignificant_digits + value.change(usec: value.usec / round_power * round_power) + end + def type_cast_for_schema(value) "'#{value.to_s(:db)}'" end |