目前我正在开发一个管理工作班次的系统。
系统包含一个端点,该端点根据服务器时间返回当前班次。我创建了一个适用于常规班次的查询,例如上午08:00到下午04:00等等,但挑战是当黎明班次从上午10:00开始到06:00 AM时。
我的模型包含以下字段:
Ps。:我使用Postgres作为数据库。
我的代码:
class Shift < ApplicationRecord
def self.current
current_time = Time.now()
current_time = current_time.change(year: 2000, month: 1, day: 1)
@current ||= Shift
.where('start_time <= ?', current_time)
.where('end_time >= ?', current_time)
.first()
end
end
Ps。:我想,因为我在数据库中使用Time类型,我必须将 Time.now 标准化为使用2000 - 01 - 01日期。
那么,有没有一种简单/最好的方法呢?
感谢您的帮助!
答案 0 :(得分:1)
有趣的问题!所以有两种情况:(1)正常班次(start_time <= end_time
),以及(2)与午夜重叠的班次(start_time > end_time
)。
您已经通过检查当前时间是否在开始时间和结束时间之间来处理第一种情况。
我相信第二种情况可以通过检查当前时间 在开始时间和午夜之间,或在午夜和结束时间之间来处理。这转换为start_time <= ? OR end_time >= ?
。
我有一段时间没有使用Rails,但我认为你可以这样做:
@current ||= Shift
.where('start_time <= end_time')
.where('start_time <= ?', current_time)
.where('end_time >= ?', current_time)
.or(Shift
.where('start_time > end_time')
.or(Shift
.where('start_time <= ?', current_time)
.where('end_time >= ?', current_time)))
.first()
如果你这样做,考虑将这两个案例分成单独的scopes,这样你就可以在这个方法中写出更像这样的东西:
@current ||= current_normal_shifts.or(current_dawn_shifts).first
答案 1 :(得分:0)
您可能会对提供TimeOfDay
类的tod gem和Shift
类感兴趣,该类需要两个TimeOfDay
个对象来表示班次的开始和结束。它按预期处理黎明班次。
实现可能如下所示:
require 'tod'
class Shift < ApplicationRecord
def self.current
find(&:current?)
end
def current?
schedule.include?(Tod::TimeOfDay(Time.now))
end
def schedule
Tod::Shift.new(Tod::TimeOfDay(start_time), Tod::TimeOfDay(end_time))
end
end