I am upgrading a Rails app from
- Rails 4.2 -> 5.2 (a subsequent upgrade to Rails 6 is pending)
- Ruby 2.2 -> 2.5
- Postgres 9.1 -> 10
in various steps. Since the Rails upgrade requires the Postgres upgrade I can’t separate the upgrades in a sensible way.
Currently I am struggling with the way “Time” objects are handled in Rails 5.2. A “time” column in an AR object is now returned as an
ActiveSupport::TimeWithZone, even if the database column has no time zone. Previously it was a plain
Time object which had a different default JSON representation.
This makes a lot of API tests fail which were previously all returning UTC times.
Example for Rails 4.2, Ruby 2.2, PG 9.1 for a
2.2.6 :002 > p.time_weekdays_from => 2000-01-01 07:00:00 UTC 2.2.6 :003 > p.time_weekdays_from.class => Time
Example for Rails 5.2, Ruby 2.5, PG 10:
irb(main):016:0> p.time_weekdays_from => Sat, 01 Jan 2000 11:15:00 CET +01:00 irb(main):018:0> p.time_weekdays_from.class => ActiveSupport::TimeWithZone
I have added an initializer to override this for the time being and this seems to work fine, but I’d nevertheless like to understnand why this change has been made and why even ‘time without time zone’ DB columns are being treated by Rails as if they had a timezone.
# This works, but why is it necessary? module ActiveSupport class TimeWithZone def as_json(options = nil) self.utc.iso8601 end end end
PS: I don’t always want UTC, I just want it for the API because that’s what our API clients expect.