Reputation: 3
I am making an appointment, scheduling API. I have many starttime and endtime pairings in DateTime format. I need to be sure that when I create a new appointment that times do not overlap with previous ones. What I mean is that if I have an appointment starting at 7/4/15 9:00 and ending at 7/4/15 13:00 I want to make a validation so that I can't make a new appintment starting at 7/4/15 10:00 ending at 7/4/15 12:00. I want to compare all the key value pairs to make sure the new one doesn't fall inside that range. Any ideas how I can do this?
Upvotes: 0
Views: 365
Reputation: 8898
class Appointment < ActiveRecord::Base
validate :duration_not_overlap
private
def duration_not_overlap
verify_time(:starttime)
verify_time(:endtime)
end
# attr is :starttime | :endtime
def verify_time(attr)
errors[attr] << 'overlap' if Appointment.where(user_id: user_id, attr => (starttime..endtime)).exists?
end
end
Upvotes: 0
Reputation: 36860
An overlap happens when you have an a appointment that starts before this appointment ends, and ends after this one starts. If there are no appointments that fit that criteria, there are no overlaps.
Note that you need to also consider the special case that searching for appointments will find one overlap but it's the appointment you're currently editing, so you can ignore that one.
class Appointment < ActiveRecord::Base
validate :no_overlapping_appointments
def no_overlapping_appointments
overlaps = Appointment.where('start_time <= ? AND end_time >= ?', end_time, start_time)
return if overlaps.empty?
return if overlaps.count == 1 && overlaps.first.id == id
errors.add(:start_time, "This appointment overlaps others")
end
end
Upvotes: 1