Ruby on rails 在Rails模型中使用持续时间字段
我正在寻找在Rails模型中使用duration字段的最佳方法。我希望格式是HH:MM:SS(ex:01:30:23)。正在使用的数据库是本地sqlite和生产中的Postgres 我还想使用此字段,以便查看字段中的所有对象,得出该模型中所有对象的总时间,最后得出如下结果: 30条记录,共计45小时25分34秒 那么什么才是最有效的呢Ruby on rails 在Rails模型中使用持续时间字段,ruby-on-rails,ruby,time,duration,Ruby On Rails,Ruby,Time,Duration,我正在寻找在Rails模型中使用duration字段的最佳方法。我希望格式是HH:MM:SS(ex:01:30:23)。正在使用的数据库是本地sqlite和生产中的Postgres 我还想使用此字段,以便查看字段中的所有对象,得出该模型中所有对象的总时间,最后得出如下结果: 30条记录,共计45小时25分34秒 那么什么才是最有效的呢 迁移的字段类型 CRUD表单的表单字段(小时、分钟、秒下拉列表?) 生成模型中所有记录的总持续时间的最便宜方法 在数据库中存储为整数(可能是秒数) 您的输入表
- 迁移的字段类型
- CRUD表单的表单字段(小时、分钟、秒下拉列表?)
- 生成模型中所有记录的总持续时间的最便宜方法
- 在数据库中存储为整数(可能是秒数)
- 您的输入表单将取决于具体的用例。跌落是痛苦的;最好在小时+分钟+秒的持续时间内使用小文本字段
- 只需在duration列上运行一个
查询,即可生成一个总计。如果你使用整数,这是简单而快速的SUM
- 使用辅助对象在视图中显示持续时间。通过使用
(用数据库中的整数替换123.seconds
),您可以轻松地将持续时间转换为秒整数。使用123
检查生成的inspect
格式。(这并不完美。你可能想自己写点东西。)Duration
- 在您的模型中,您可能需要返回/获取
对象而不是整数的属性读取器和写入器。只需定义ActiveSupport::Duration
和duration=(new\u duration)
,它们在内部使用整数参数调用duration
/read\u属性
write\u属性
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
类完成
我编写了一些存根来支持和使用PostgreSQL的interval
类型为ActiveRecord::Duration
请参阅此要点(您可以在Rails 4.1中将其用作初始值设定项):
我还打开了对Rails的pull请求:
在Rails 5中,您可以使用ActiveRecord::Attributes将ActiveSupport::Durations存储为ISO8601字符串。使用ActiveSupport::Duration优于整数的优点是,您可以直接使用它们进行日期/时间计算。你可以做一些事情,比如
Time.now+1.month
,它总是正确的
以下是方法:
添加config/initializers/duration\u 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)
模型
我从来没有考虑使用秒,doh!谢谢你的提示!如何使用
inspect
格式化输出?示例?我们为Rails 5.1编写了更新的要点:
create_table :somethings do |t|
t.string :duration
end
class Something < ApplicationRecord
attribute :duration, :duration
end
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