Reputation: 2718
My view (haml):
= f.time_zone_select :time_zone, nil, {}, class: 'form-control'
Renders to:
...
<option value="Ljubljana">(GMT+01:00) Ljubljana</option>
<option value="Madrid">(GMT+01:00) Madrid</option>
<option value="Paris">(GMT+01:00) Paris</option>
<option value="Prague">(GMT+01:00) Prague</option>
...
When creating a record I want to set the :time_zone
attribute to the current time zone of the user. There are several ways to do this but after researching I found either the gem timezone_local
or the JS library jstz
most common ones.
Either way, all those open source libraries seem to use a different pattern then rails does, e.g the Paris timezone is defined as:
Europe/Paris
However, the TimeZone object in Rails uses
Paris
this leads to inconsistencies when I want to create a record with the current time zone of the user as it won't match. I need rails to use the same patterns as jstz
or vice versa but I don't want to gsub
strings here or similiar.
What is the best approach here?
Upvotes: 7
Views: 1779
Reputation: 20694
Use .select
instead of .time_zone_select
:
<%= f.select :timezone, ActiveSupport::TimeZone.all.collect {|tz| ["(GMT#{ActiveSupport::TimeZone.seconds_to_utc_offset(tz.utc_offset)}) #{tz.name}", tz.tzinfo.name]}, { include_blank: true } %>
Upvotes: 3
Reputation: 4570
You can use Draper to modify all
and name
(the list and value methods used by time_zone_select
):
class TimeZoneDecorator < Draper::Decorator
decorates ActiveSupport::TimeZone
delegate_all
def self.all
TimeZoneDecorator.decorate_collection(ActiveSupport::TimeZone.all)
end
def self.us_zones
TimeZoneDecorator.decorate_collection(ActiveSupport::TimeZone.us_zones)
end
# other custom collection methods
def name
tzinfo.name # "Europe/Paris" instead of "Paris"
end
end
And then use the model
option in your tag:
= f.time_zone_select :timezone, TimeZoneDecorator.us_zones, {include_blank: "Set from Lat/Lng", model: TimeZoneDecorator}, {class: 'form-control'}
Upvotes: 2