mwi*_*ams 28 ruby time duration ruby-on-rails
我正在寻找在Rails模型中使用持续时间字段的最佳方法.我希望格式为HH:MM:SS(例如:01:30:23).正在使用的数据库是本地的sqlite和生产中的Postgres.
我还想使用这个字段,这样我就可以看一下该字段中的所有对象,并得出该模型中所有对象的总时间,最后得到如下结果:
30条记录共计45小时25分34秒.
那么什么最适合?
mol*_*olf 42
SUM在持续时间列上运行查询即可生成总计.如果使用整数,这很容易,也很快.另外:
ActiveSupport::Duration通过使用123.seconds(替换123为数据库中的整数)轻松地将持续时间转换为整数秒.inspect在结果上使用以获得Duration良好的格式.(这不完美.你可能想自己写点东西.)ActiveSupport::Duration对象,而不是整数.只需定义duration=(new_duration)和duration,内部调用read_attribute/ write_attribute使用整数参数.Ant*_*ang 12
在Rails 5中,您可以使用ActiveRecord :: Attributes将ActiveSupport :: Durations存储为ISO8601字符串.使用ActiveSupport :: Duration而不是整数的优点是,您可以立即使用它们进行日期/时间计算.你可以这样做Time.now + 1.month,而且总是正确的.
这是如何做:
加 config/initializers/duration_type.rb
class DurationType < ActiveRecord::Type::String
def cast(value)
return value if value.blank? || value.is_a?(ActiveSupport::Duration)
ActiveSupport::Duration.parse(value)
end
def serialize(duration)
duration ? duration.iso8601 : nil
end
end
ActiveRecord::Type.register(:duration, DurationType)
Run Code Online (Sandbox Code Playgroud)
移民
create_table :somethings do |t|
t.string :duration
end
Run Code Online (Sandbox Code Playgroud)
模型
class Something < ApplicationRecord
attribute :duration, :duration
end
Run Code Online (Sandbox Code Playgroud)
用法
something = Something.new
something.duration = 1.year # 1 year
something.duration = nil
something.duration = "P2M3D" # 2 months, 3 days (ISO8601 string)
Time.now + something.duration # calculation is always correct
Run Code Online (Sandbox Code Playgroud)
我尝试使用ActiveSupport :: Duration但是无法清除输出.
你可能喜欢ruby-duration,一种不可变的类型,代表一些精确的时间,以秒为单位.它有很多测试和Mongoid模型字段类型.
我也想轻松地解析人类持续时间的字符串,所以我选择了慢性持续时间.以下是将其添加到具有time_spent in seconds字段的模型的示例.
class Completion < ActiveRecord::Base
belongs_to :task
belongs_to :user
def time_spent_text
ChronicDuration.output time_spent
end
def time_spent_text= text
self.time_spent = ChronicDuration.parse text
logger.debug "time_spent: '#{self.time_spent_text}' for text '#{text}'"
end
end
Run Code Online (Sandbox Code Playgroud)