Rails:使用不需要的格式保存活动记录 time:type

Rails: active record saving time:type with unwanted format

我有一个 table 属性为 hour 的 call periodo。我以这种方式传递我的时间参数

hour = Time.parse( splitLine[1] ) #where splitLine[1] is my time but in string
periodo = Periodo.new(:hour => hour.strftime("%H:%M"))
periodo.save

但活动记录以这种方式保存记录小时:“2000-01-01 07:00:00”,我已经在/config/initializers/time_formats.rb

中设置了格式
Time::DATE_FORMATS[:default] = "%H:%M"
Date::DATE_FORMATS[:default] = "%H:%M"

也在en.yml

  en:
    hello: "Hello world"
    time:
      formats:
        default: "%H:%M"
    date:
      formats:
        default: "%H:%M"

但我的记录仍在保存年和月:(我必须做些什么才能只保存小时和分钟???

问候

你什么都不用做。这是关于时间存储的 activerecord 约定。因此,如果你想从 sql 数据库中自动解析模型中的时间,你必须以 AR 的方式存储它。但是如果你真的只想存储小时和分钟,你应该改变你的方案并在 AR 迁移中只使用字符串而不是日期时间。所以你可以像那样存储你的时间。在模型 class 中,您可以覆盖属性 getter,例如:

def some_time
  Time.parse(@some_time)
end

然后在调用属性的时候就可以得到解析出来的时间对象。但这实际上是一种糟糕的方式。

日期格式仅在您的应用程序中有效,在数据库中无效 - 它们仅负责时间对象向您的用户显示的方式,不会影响数据的存储方式。

不幸的是,数据库中没有时间这样的概念(至少我没有听说过,相信我,我确实搜索过它,因为我在当前项目中需要它)

最简单的解决方案

但是,在许多情况下,只存储事件的时间是有意义的。在当前的项目中,我们决定以整数 60 * hour + minutes 的格式存储它。不幸的是,这是我们在项目中停止的地方。 :(

更进一步

然后您可以创建一个助手 class(只是一个脚手架 - 需要做更多工作,例如验证转换等):

class SimpleTime
  attr_accessor :hour, :minute

  def initialize(hour, minute)
     @hour, @minute = hour, minute
  end

  def self.parse(integer)
    return if integer.blank? 
    new(integer / 60, integer % 60)
  end

  def to_i
    60 * @hour + @minute
  end
end

然后覆盖 setter 和 getter:

class Model < ActiveRecord::Base
  def time
    @time ||= SimpleTime.parse(super)
  end

  def time=(value)
    super(value.to_i)
  end
end

更多乐趣

现在您可以做的事情更多了。例如,您可以将扩展名 simple_time 写入 active_record,这将自动重新定义 setters 和 getters 以获取传递的属性列表。您甚至可以将它包装在一个小的 gem 中并使其在现实世界中得到证明(缺少验证、字符串格式解析器、处理 _before_type_cast 值等)。