如何从验证方法中获取模型ID

时间:2013-09-27 10:59:31

标签: ruby-on-rails ruby-on-rails-4

在我的一个验证中,我想确保用户日期范围输入与现有存储的日期范围不重叠:

class Timecard < ActiveRecord::Base
  validate :does_not_intersect_with_existing_timecards

  def does_not_intersect_with_existing_timecards
    if from_date && to_date &&
      !Timecard.where("? <= to_date AND ? >= from_date", from_date, to_date).empty?
      errors.add(:from_date, "must not intersect with existing timecards")
    end
  end
end

问题是如果从update方法调用此验证将失败(因为where子句将在数据库中找到当前正在更新的记录)。我不想仅验证on: :create,因为用户可能会修改日期范围。

如何从验证查询中排除当前模型?

我似乎无法在验证方法中访问id@id ...

2 个答案:

答案 0 :(得分:2)

试试这个

def does_not_intersect_with_existing_timecards
  if self.new_record?  
     errors.add(:from_date, "must not intersect with existing timecards") if from_date && to_date && !Timecard.where("? <= to_date AND ? >= from_date ", from_date, to_date).empty?
  else
     errors.add(:from_date, "must not intersect with existing timecards") if from_date && to_date && !Timecard.where("? <= to_date AND ? >= from_date AND id != ?", from_date, to_date, self.id).empty?
  end

end

OR

def does_not_intersect_with_existing_timecards
   errors.add(:from_date, "must not intersect with existing timecards") if from_date && to_date && !Timecard.where("#{self.new_record? || 'id != ' + self.id.to_s} AND ? <= to_date AND ? >= from_date ", from_date, to_date).empty?
end

答案 1 :(得分:1)

您可以使用before_save挂钩代替validation