Custom Validator

I have an app that allows you to book meeting rooms, and I am trying to make it so you cannot book a room if the time slot has already been taken.

Here are 2 examples:

  1. If somebody want’s to book a time slot from 12:00 - 13:00 somebody else should not be able to book that same slot
  2. If somebody want’s to book a time slot from 12:00 14:00 somebody else should not be able to book 13:00 - 15:00 as this will overlap.

This is my current validation code:

class MeetingValidator < ActiveModel::Validator
  def validate(record)
    if record.class.where(to: record.to..record.from).where(from: record.to..record.from)
      record.errors[:time_slot] << "has already been taken, please pick another"
    end 
  end
end

Any help is much apreciated.

So you can just as easily have this as a class method. Defining a custom validator is usually reserved for when you want to use it across multiple models.

I would go for the following:

class Meeting < ActiveRecord::Base
  validates :time_slot_is_available

  private

  def time_slot_is_available
    if <logic checking meetings with the same slot>
      record.errors[:time_slot] << "has already been taken, please pick another"
    end
  end
end

Another thought is, are your users picking time slots from a drop-down? It might be a good user experience to only show available slots to pick. You should leave the validation in there in case someone gets the slot just before someone else submits.

What’s the problem you’re having?

@halogenandtoast helped me with this in the Office Hours thanks guys.

The solution was this:

def valdiate_time_slot(record)
  if record.class.where("`to` > ? AND `from` < ?", record.from, record.to).exists?
    record.errors[:time_slot] << "has already been taken please choose another."
 end
end