Yakram
Yakram

Reputation: 3

How can I check if a new event (start time - endtime) doesn't overlap with previous startime - endtimes (Ruby)

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

Answers (2)

Aetherus
Aetherus

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

SteveTurczyn
SteveTurczyn

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

Related Questions