【问题标题】:Rails: How to manage a "static" time-value attribute?Rails:如何管理“静态”时间值属性?
【发布时间】:2019-08-31 18:14:53
【问题描述】:

Rails 拥有一个“时间”属性(由用户选择)的最佳方式是什么?该属性应该始终显示为相同的“静态”时间值?

(意思:它应该始终显示相同的时间,例如“14:00”,完全独立于任何用户的时区和/或 DST 值。)

到目前为止,我已经尝试了以下设置:

  • 在 MySQL 数据库中,我使用 time 类型的字段(即格式为:14:00:00
  • 在 Rails 视图中,我使用 helper time_select(因为它真的很方便)

但是,通过这种方法,Rails 的 ActiveRecord 会将此时间值视为成熟的 Ruby Time 对象,因此将值 (14:00:00) 转换为默认时区(通常设置为'UTC') 用于存储,然后将其转换回用户的时区,以供查看。而且如果我没记错的话,这也意味着波动的 DST 值会使显示的时间值全年波动(如果用户移动到另一个时区也会发生同样的情况)。

那么使用 Rails 管理简单的“静态”时间属性的最佳方法是什么?

【问题讨论】:

    标签: ruby-on-rails time timezone


    【解决方案1】:

    如果您不想要任何与时间相关的功能,为什么不将其保存为字符串字段。由于从您的问题描述中可以明显看出时区等功能不会影响您的用例,因此只需将其设为普通 VARCHAR(8) 并将值保存为字符串并解析它,例如 Time.now.strftime("%H:%M:%S") 然后将其保存到数据库,您也可以在 ActiveRecrd 模型类中编写此逻辑

    def static_time=(value)
      super(value.strftime("%H:%M:%S"))
    end
    

    你可以在代码中的某处说model_object.static_time=Time.now,这会自动解析它,如果你想将时间作为一个保留格式的ruby对象获取,你可以简单地定义一个自定义getter。

    def static_time
      current_time = Time.now
      time_keys = [:hour, :min, :sec]
      current_time.change(**Hash[time_keys.zip(super.split(":"))])
    end
    

    【讨论】:

    • 谢谢 - 我似乎唯一需要纠正的是你的吸气剂,因为Time.now.hour= 不是有效的二传手。所以该方法需要类似于:Time.new(Time.now.year, nil, nil, super.split(":")[0], super.split(":")[1], super.split(":")[2])
    • @TomDogg 啊感谢您指出。更新了我认为更好的方法的答案。
    猜你喜欢
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 2015-11-03
    • 1970-01-01
    相关资源
    最近更新 更多