我正在尝试为一段时间创建验证,因此一段时间内不包含其他句号。
即第一期是25-30,第二期是20-40,应该是错误
我试图通过
来验证它def period_cannot_inbetween_and_other_period
return unless period_overlap(start_week, finish_week).any?
errors.add(:start_week, '-', :finish_week, 'cannot be in another Period')
end
和
def period_overlap(start_week, finish_week)
self.class.where(':start_week <= start_week AND :finish_week >= finish_week', start_week, finish_week)
end
整个代码在
之下class Period < ApplicationRecord
has_many :days_till_sellables, dependent: :destroy
belongs_to :organization
validates :name, presence: true
validates :start_week, presence: true
validates :finish_week, presence: true
validates :start_week, inclusion: { in: (1..52), message: '%<value>s must be a valid week number' }
validates :finish_week, inclusion: { in: (1..52), message: '%<value>s must be a valid week number' }
validate :start_week_cannot_overlap_period
validate :finish_week_cannot_overlap_period
validate :start_week_cannot_overlap_period_wrap_around
validate :finish_week_cannot_overlap_period_wrap_around
validate :period_cannot_inbetween_and_other_period
protected
def start_week_cannot_overlap_period
return unless regular_overlap(start_week).any?
errors.add(:start_week, 'cannot be in another Period')
end
def finish_week_cannot_overlap_period
return unless regular_overlap(finish_week).any?
errors.add(:finish_week, 'cannot be in another Period')
end
def start_week_cannot_include_period
return unless regular_overlap(start_week).any?
errors.add(:start_week, 'cannot be in another Period')
end
def start_week_cannot_overlap_period_wrap_around
return unless finish_week > start_week && year_end_overlap(start_week).any?
errors.add(:start_week, 'cannot be in another Period')
end
def finish_week_cannot_overlap_period_wrap_around
return unless finish_week > start_week && year_end_overlap(finish_week).any?
errors.add(:finish_week, 'cannot be in another Period')
end
def period_cannot_inbetween_and_other_period
return unless period_overlap(start_week, finish_week).any?
errors.add(:start_week, '-', :finish_week, 'cannot be in another Period')
end
def regular_overlap(week_of_year)
self.class.where('start_week <= :week_of_year AND finish_week >= :week_of_year', week_of_year: week_of_year)
end
def year_end_overlap(week_of_year)
self.class.where('finish_week < start_week AND (start_week <= :week_of_year OR finish_week >= :week_of_year)',
week_of_year: week_of_year)
end
def period_overlap(start_week, finish_week)
self.class.where(':start_week <= start_week AND :finish_week >= finish_week', start_week, finish_week)
end
end
答案 0 :(得分:0)
因此,如果在[start..end]中包含original_start或original_end,或者[original_start ..original_end]中包含[start..end],则周期重叠,对于最后一种情况,只检查一个边界就足够了。
scope :ovelapped_periods, ->(start, finish) { where(start_week: (start..finish)).or(end_week: (start..finish)).or(where(arel_table[:start_week].lt(start)).where(arel_table[:end_week].gt(start))) }
我建议只留下一个验证,以使代码更具可读性
validate :overlapping_period
def overlapping_period
if self.class.ovelapped_periods(start_week, end_week).where.not(id: id).any?
errors.add(:start_week, 'Period is overlapped other periods')
end
end