Skip to main content

How can one setup a service booking app with time limitations?

Rails • Asked by Drilon Buzuku

Hey guys,

how can one setup a service booking system where the customer can book services between 9am and 4pm on every monday and friday? Would you use the ice_cube gem to create timeslots and then suggest the customer appointments in a given time frame? How would you approach this kind of problem?

Kind regards,

Drilon


Hi Drilon,

I did this for a project a while back, it was a booking app for a salon that had various services all with different appointment durations. I didn't use any gems to manage the time slots since in a single day there can only be so many slots available so the calculations to determine if a slot was available is pretty straight forward.

The general gist to determine if a slot is available is to take the operating hours range and split it into an array of possible appointment slots. So if your shop is open from 9am-5pm, and your appointment has a duration of 1 hour, you can determine that there are potentially 7, 1-hour appointment slots. Now get a list of already booked appointments and remove those times from the array of potential time slots. The time slots left over are now slots that are available that don't overlap with another appointment.

This is the basic function I made that checks if a slot is available or not:

base_time_range.each do |slot|
      overlap = unavailable.map { |booked| (booked[0]...(booked[0] + booked[1].hours)).overlaps?(slot...(slot + time_range[1].hours)) }
     !overlap.include?(true) ? available_slots << slot : ''
end

base_time_range is an array of potential time slots, unavailable is an array of already booked times - iterate over each base_time_range and check if it overlaps the time of an already booked appointment, if it doesn't overlap, add it to the available_slots array.

A couple of things that make appointment bookings a major PITA - if your app will have to deal with people / businesses that have daylight savings time, then you have to be sure that you're checking if the time selected is currently in daylight savings time (dst? method) and adjust accordingly. Also, appointment bookings are extremely susceptible to race conditions, so you need to have a way of holding a time slot while a customer is completing their checkout process.

Also note, I had never done a booking app before, this was my first time doing one and I was still pretty new to ruby/rails so my way may not be all that great - but it's been in production for almost 2 years now and there's been no issues so far, so I guess that's a win!


Thanks for answering Jacob! I appreciate it. Seems like a good way to tackle the problem! :)


Hi Jacob, what did you use for the appointment selection in the view? A calendar?


Hey Luca,

Yes, I used Chris' Simple Calendar to handle the calendar.

In the image below, the user is first presented with all the dates of the month. When a user selects a day, it does an AJAX request to determine what the available slots are for that day, then presents them with the available dates.

Once a user selects a timeslot, the rest of the form appears and they can fill out their info. In order to deter race conditions, when a user selects a timeslot, it is saved to a HoldTime table which will make that slot appear unavailable to anyone else who visits within X amount of time (I forget the limit I set, maybe 3-5 mins)


Thank for sharing your solution Jacob (and Drilon for asking this question before me!)

I am going to use fullcalendar to display available appointments (clickable). Staff users will need to enter the session length before they can open the calendar with the available options.

The calendar will use ajax to access the available slots from the user controller. The controller will remove all existing bookings for the specific consultant in the appointments table and return all remaining available ones. The use of slots (15minutesx96) will help with dealing with different appointment lenghts.

Luca


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 22,346+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.