Reputation: 973
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
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