user4965201
user4965201

Reputation: 973

Validate if new range overlaps existing range

I have a Range model which has a start_range and an end_range column.

My range.rb model:

class Range < ActiveRecord::Base
  validate :range_valid

  protected

  def range_valid
    range = Range.all
    range.each do |f|
      if (f.start_range..f.end_range).overlaps?(self.start_range..self.end_range)
        self.errors.add(:base, 'range is already alloted')
        break
      end
    end
  end
end

This code takes the start_range and end_range (say 100 and 500) and matches all the database records if any range overlap (or say the two ranges must be completely exclusive ) with the range which the user have entered.

This code is working fine but this code is not feasible if there are millions of records stored in the database

Can anyone please tell me how can I match the overlapping of the range without using loop and fetching all the records by Range.all so that the code should be feasible for real time.

Upvotes: 1

Views: 577

Answers (1)

davegson
davegson

Reputation: 8331

You can easily query Range to check if an existing range overlaps with the given range.

Range.where("end_date >= ?", start_of_a_range).where("start_date <= ?", end_of_a_range).count

To wrap this into a validator I'd first define a scope

range.rb

scope :in_range, ->(range) { where("end_date >= ?", range.first).where("start_date <= ?", range.last) }

And then add the validator:

validates :range_cannot_overlap

def range_cannot_overlap
  if Range.in_range(start_range..end_range).count > 0
    errors.add(:base, 'range is already alloted')
  end
end

Upvotes: 4

Related Questions