Railsvalidation日期范围的唯一性

我有一个涉及员工缺勤记录的申请。

我需要确保每条记录的开始和结束日期不重叠。

因此,例如,如果我输入了今天开始并明天结束的缺席记录,则不应该以任何方式在该日期范围内输入另一个记录。 所以我不能制作一个在今天前一天开始,然后在后天或之后的任何日期结束。

简单地说,我需要使日期范围独特。

实现这一目标的最佳方法是什么?

模型类中涉及遍历所有记录的自定义validation器需要很长时间才能完成,而且我没有找到任何解决此问题的gem。 我也没有找到任何简单的方法来确定模型中的唯一性。 我很难过:/

谢谢你的时间!

编辑:

class Absence  true, :message => "can only be whole number." end 

我用这些:

  scope :overlaps, ->(start_date, end_date) do where "(DATEDIFF(start_date, ?) * DATEDIFF(?, end_date)) >= 0", end_date, start_date end def overlaps? overlaps.exists? end # Others are models to be compared with your current model # you can get these with a where for example def overlaps siblings.overlaps start_date, end_date end validate :not_overlap def not_overlap errors.add(:key, 'message') if overlaps? end # -1 is when you have a nil id, so you will get all persisted user absences # I think -1 could be omitted, but did not work for me, as far as I remember def siblings user.absences.where('id != ?', id || -1) end 

资料来源: https : //makandracards.com/makandra/984-test-if-two-date-ranges-overlap-in-ruby-or-rails

作为对已接受答案的修改,这里是一个重叠范围,适用于不理解DATEDIFF的DB

  scope :overlaps, ->(start_date, end_date) do where "((start_date <= ?) and (end_date >= ?))", end_date, start_date end 

这借鉴了确定两个日期范围是否重叠的解决方案

使用gem validates_overlap

 gem 'validates_overlap' 

例如,如果您有一个名为Meeting的模型,其类型为datestart_dateend_date字段,则可以轻松validation它们是否重叠。

 class Meeting < ActiveRecord::Base validates :start_date, :end_date, overlap: true end 

另一个更现实的例子,比如Meeting属于User ,您可以将其范围化,因此它仅validation特定用户的会议。

 class Meeting < ActiveRecord::Base belongs_to User validates :start_date, :end_date, overlap: { scope: 'user_id', message_content: 'overlaps with Users other meetings.' } end 

有一个名为validates_overlap的gem,可以让您轻松validation日期范围重叠。 您还可以在validation中使用范围。

虽然juanpastas解决方案是正确的,但它对于创建记录是有效的,但可能导致对更新的错误否定validation。

如果您需要编辑现有记录,请说范围是2014-03-13..2014-06-12并且您希望将其缩小到2014-03-13..2014-04-12,您将得到一个重叠错误,因为它正在检查AGAINST本身。

  def siblings Absence_users.where('user_id = ? AND id != ?', user_id, self) end 

将消除这个缺点。 (Dave T的添加也应该遵循,与DB无关。)