时间范围方法在 Rails 4/Ruby 2 应用程序中不起作用

Time range method not working in Rails 4/Ruby 2 app

我需要帮助解决 Rails 4/Ruby 2.0 应用程序中的时间范围问题。在我的约会模型中,我想防止用户在营业时间以外进行约会,即 6:30 a.m。到 9:00 p.m。该模型在名为 appointment_date 的列中跟踪约会时间,该列属于 DateTime 数据类型。

我尝试通过将以下方法放在 app/validators 目录中来解决问题:

class DuringBusinessHoursValidator < ActiveModel::EachValidator

def validate_each(record, attribute, value)    
unless value.present? && during_business_hours(value)
record.errors[attribute] << 'must be during business hours (6:30 am - 9:00 pm)'
end
end

def during_business_hours(time)
# from     
Range.new(
Time.local(time.year, time.month, time.day, 6, 30),
Time.local(time.year, time.month, time.day, 21, 0)) === time
end
end

我将以下代码放入我的约会模型中:

validates :appointment_date, during_business_hours: true

但是,Rails 抛出以下错误:

TypeError in AppointmentsController#update
can't iterate from Time

当我删除方法中的一个 === 符号时,Rails 不会生成错误,但代码无法正确运行。使用 == 时,所有约会都会受到限制,即使是那些发生在 6:30 am 和 9:00 pm 之间的约会。

我阅读了另一个 Whosebug post,其中有人报告了使用 Ruby 2.0 执行上述方法时出现的问题。这个人说他们通过 "converting the range endpoints with .to_i, and then comparing with t.to_i." 解决了这个问题,所以,我将第二种方法中的代码更改如下:

def during_business_hours(t)

t = Time.now

Range.new(
Time.local(t.year, t.month, t.day, 6, 30).to_i,
Time.local(t.year, t.month, t.day, 21).to_i
) === t.to_i
end
end

但是,该更改不起作用。它会产生相反的问题:Rails 允许所有约会,无论时间如何。

对于如何进一步排除故障并解决问题有什么想法或建议吗?如果有任何帮助,我将不胜感激!

我会利用 DateTime 对象支持比较这一事实。例如

   Time.local(2014, 12, 31, 6, 30) > Time.local(2015, 1, 1, 6, 30)
   => false

因此您可以重写方法 during_business_hours:

   # Check if time `t` is between 6:30 and 21:00 of `t`'s day, a.k.a. in between business hours.
   # If that's the case, return true, otherwise false.
   def during_business_hours(t)
     if t < Time.local(t.year, t.month, t.day, 6, 30) ||
        t > Time.local(t.year, t.month, t.day, 21)
        return false
     else
        return true
     end
   end

就个人而言,您当前的该方法的代码很难阅读,新版本更加清晰。

...顺便说一句,我会将其设为 private 方法。

def validate_each [snip]

private

def during_business_hours(t)
  [snip]