Rails验证方法比较两个字段?

时间:2011-06-19 08:34:49

标签: ruby-on-rails ruby ruby-on-rails-3

我的模型有两个字段,我想在验证过程中相互比较。我想确保end_time在start_time之后。我已经编写了一个验证方法来比较它们,但我必须做错了,因为值总是为零。有人可以帮忙吗?

class LogEntry < ActiveRecord::Base
  validates :start_time, :presence => { :message => "must be a valid date/time" }
  validates :end_time, :presence => {:message => "must be a valid date/time"}
  validate :start_must_be_before_end_time

  def start_must_be_before_end_time
    errors.add(:start_time, "must be before end time") unless
       start_time > end_time
  end 
end

收到错误

undefined method `>' for nil:NilClass

因此,start_time和/或end_time为零。我以为我跟着我发现的很多例子,但显然不是。我错过了什么?

感谢。

5 个答案:

答案 0 :(得分:16)

我最好的猜测是你需要你的方法看起来像这样:

private

def start_must_be_before_end_time
    errors.add(:start_time, "must be before end time") unless
        start_time < end_time
end 

(另请注意<而不是>(或更改为if>=

如果这不起作用,那么您还应检查控制器中是否正确定义了start_timeend_time,因为如果跨多个表单创建时间,可能会发生有趣的事情元件。

答案 1 :(得分:5)

您需要自己检查存在(如果不存在,则跳过验证步骤)。

def start_must_be_before_end_time
  return unless start_time and end_time
  errors.add(:start_time, "must be before end time") unless start_time < end_time
end

打印“必须是有效日期/时间”或“开始时间必须在结束时间之前”。

替代

def start_must_be_before_end_time
  valid = start_time && end_time && start_time < end_time
  errors.add(:start_time, "must be before end time") unless valid
end

如果未设置start_time或end_time,则打印“开始时间必须是有效日期/时间”和“开始时间必须在结束时间之前”。

第一个的个人偏好,因为它只显示用户做错了什么。后者就像许多网站一样只是将20行错误文本加载到用户身上,因为程序员认为看到每个验证结果都会很好。糟糕的用户体验。

答案 2 :(得分:2)

清洁和清除(并在控制之下?)

我发现这是最清楚的阅读:

在您的模型中

# ...

validates_presence_of :start_time, :end_time

validate :end_time_is_after_start_time

# ... 

#######
private
#######

def end_time_is_after_start_time
  return if end_time.blank? || start_time.blank?

  if end_time < start_time
    errors.add(:end_time, "cannot be before the start time") 
  end 
end

答案 3 :(得分:0)

您可以使用validates_timeliness gem https://github.com/adzap/validates_timeliness

答案 4 :(得分:0)

start_time.to_i < end_time.to_i应该修复它。您正在尝试比较日期时间但由于某种原因它无法比较,因此在比较之前将它们转换为int。