我正在设备上创建一个状态,该状态将根据设备发回读数后的时间长度为该设备设置指示颜色。这是我目前的解决方案:
def indicator(device)
# ...
time = latest_event_time(device.id)
case
when time < 12.hours.ago
:red
when time.between?(12.hours.ago, 2.hours.ago)
:yellow
when 2.hours.ago < time
:green
else
:gray
end
end
private
def latest_event_time(dev_id)
# Get latest event time from database
end
我希望能够简单地检查time
是否在指定时间范围之前,期间或之后,可能是这样的:
time <=> (2.hours.ago...12.hours.ago)
我是否缺少一种方法,或其他更清洁的方法来实现这一目标?
答案 0 :(得分:2)
不知道你是否认为这是一种改进,但是:
color = [ [12, :red], [2, :yellow], [0, :green] ].find do |n, c|
n.hours.ago >= time
end.last
答案 1 :(得分:1)
您可以重载Range
的<=>
运算符:
class Range
# return index into a 3-element array for before, in, and after
def <=>(x)
x < self.begin ? 0 : include?(x) ? 1 : 2
end
end
def indicator(device)
# ...
time = latest_event_time(device.id) or return :gray
[:red,:yellow,:green].at (2.hours.ago...12.hours.ago) <=> time
end
关于如何将重载定义集成到rails 4项目中的一个建议是将Range
代码存储在lib/ext/range.rb
中并添加行
require 'ext/range'
到config/initializers/extensions.rb
。根据需要创建目录和文件。
答案 2 :(得分:1)
怎么样:
def time_to_color(time)
{ green: 2, yellow: 12, red: Float::Infinity }.find { |_,t|
time <= t.hours_ago }.first
end
也许我错过了一些东西,但我不知道如何归还:gray
。我这样组织它来处理将来的时间。