Categories
Development

Rails Upgrade makes default Time format change. How to revert?

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 PhoneNumber object:

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.

Leave a Reply

Your email address will not be published. Required fields are marked *