如何验证整数范围不包括在另一个整数范围内

时间:2018-04-21 06:00:23

标签: ruby-on-rails activerecord

我正在尝试为一段时间创建验证,因此一段时间内不包含其他句号。

即第一期是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

1 个答案:

答案 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
相关问题