In my Rails app, I want to show all time instances in the timezone
set by the user's preference rather than UTC.
This a common problem, and I have seen solutions to change the default UTC to one specific timezone (like EDT). I want to make the times dynamic though, and I would like to do it in my time_formats.rb
initializer on the server side. In other words, users should be able to see a time in GMT 0, GMT +1, or GMT +2 based on their preference.
I have done this in a way that works locally but breaks when pushed to Heroku. Here's what I set up.
First, I have added timezone
as a column in my Devise user model.
class AddTimezoneToUsers < ActiveRecord::Migration
def change
add_column :users, :timezone, :string
end
end
Next, I am formatting my time-formats.rb
with:
Time::DATE_FORMATS[:default] = in_time_zone("%I:%M %p")
Locally, this works great. I can change my time zone preference in Settings and it adjusts across all time instances. However, my push to Heroku has failed for the following reason:
.../bundle/ruby/2.2.0/gems/activesupport-4.0.4/lib/active_support/values/time_zone.rb:283:
warning: circular argument reference - now
remote: rake aborted!
remote: NoMethodError: undefined method `in_time_zone' for main:Object
Having found in_time_zone
from the Rails class documentation, why is it working locally but causing a method issue in Heroku?
EDIT 1: Just had another thought, and I wanted to add some other debugging. Since it is a method error, I now checked my ApplicationController.
before_filter :set_timezone
def set_timezone
tz = current_user ? current_user.timezone : nil
Time.zone = tz || ActiveSupport::TimeZone["London"]
end
Since that is setting the default as London before a user changes current_user.timezone
, I don't think it should conflict. Wanted to include though.