如何基于Time.zone在time_zone_select中正确设置默认值(缩写名称还是扩展名称)?

时间:2019-05-27 12:33:28

标签: ruby-on-rails

最近我们发现time_zone_select的默认设置不正确。我认为这可能是自升级到Rails 5以来的事情。总之,我们有以下代码:

f.time_zone_select :timezone, nil, { default: Time.zone.name }

这里的问题是time_zone_select编译了一个选项列表,其中的值是“缩写”名称,我的意思是(例如)Amsterdam而不是Europe/Amsterdam

现在使用Time.zone.name设置默认值时会出错,因为它将返回Europe/Amsterdam。结果,未选择默认值。

这是一个错误还是我在这里忽略了什么?

1 个答案:

答案 0 :(得分:0)

深入研究表明,在ActiveSupport :: TimeZone的5.1.6.2版中,time_zone_select的工作方式如文档所述,使我们可以简单地通过Time.zone.name选择有效的默认时区。尽管默认值是例如“欧洲/阿姆斯特丹”,但选择选项同时包含“阿姆斯特丹”和“欧洲/阿姆斯特丹”。

所以我想Rails 5.2.0中对ActiveSupport :: TimeZone所做的更改没有充分考虑到这些对time_zone_select的影响。目前,我没有使用扩展时区名称(例如“欧洲/阿姆斯特丹”)来选择time_zone_select默认值,而是将其显式规范化为缩写形式,例如:

# As of Rails 5.2.0 the time_zone_select helper does not accept time zones in format "Europe/Amsterdam"
# anymore. Instead, we should cast this to a selectable value, being "Amsterdam" in this example.
def selectable_time_zone_name(zone_name)
  ActiveSupport::TimeZone.all.find{|tz| tz =~ zone_name }&.name
end

然后我们可以这样使用它(这包括迁移timezone属性可能已经具有的任何扩展名称值):

<% form.object.timezone = selectable_time_zone_name(selectable_time_zone_name(form.object.timezone) || Time.zone.name) %>
<%= form.time_zone_select :timezone %>