Building an order booking system in Rails

I want to create a mail-order booking application with the following characteristics: - Users can be service providers or buyers - Service providers set their capabilities (but can only set their capabilities 6 months in advance) - Buyers can then book appointments based on these capabilities - each meeting based on type of service takes a different amount of time - Based on the appointment the buyer chooses, a different set of options is displayed depending on how long the service takes

What I have created is the following: - A model TimeSlot

where I create some generic 30 minute time slots based on the start_time

and attributes end_time

. To make these time slots 6 months in the future, I have a background job running every day that creates all the new time slots needed

class TimeSlot < ActiveRecord::Base
  has_many :user_time_slots
  # ... more methods below
end

      

- A UserTimeSlots

, which basically represents the service provider's availability that they can establish. So when they create user_time_slot, they essentially say they are available at that time.

class UserTimeSlot < ActiveRecord::Base 
    belongs_to :time_slot
    belongs_to :service_provider, :class_name => "User"
    belongs_to :appointment
end

      

- A model Appointment

that has many user_time_slots. It has a lot because the assignment belongs to a service that takes a certain amount of time (attribute time_required

for services) and it can span the number of consecutive user_time_slots.

class Appointment < ActiveRecord::Base
  has_many :user_time_slots
  belongs_to :buyer, :class_name => "User"
  belongs_to :service_provider, :class_name => "User"
  belongs_to :service
end

      

- A Service

, which has multiple purposes and belongs to the service provider who creates this service.

class Service < ActiveRecord::Base
  has_many :appointments
  belongs_to :service_provider, :class_name => "User"
end

      

This domain model works; however I am wondering if there is a better way to do this because of the following:

  • It seems a bit uncomfortable for me to create TimeSlot entries every day on my backend using background work - TimeSlots really have a single purpose - to have start and end times and then be associated with.

    • Once the user (buyer) selects the service they want, I do not know how I could efficiently find x the number of consecutive and long users, and therefore available to book an appointment (for example, if I have 30 minutes time slots and the user selects an appointment which will take 3 hours, I will need to find 6 consecutive time slots). For example, if a user clicks on an instance of a service, I would need to 1) get the time it takes for that service (easy enough to do) and 2) I would need to find ALL of the user's user_time_slots and collect their associated time_slots and then compare each start time and the end of the time interval with each other to find consecutive. It just looks like too many iterations for me and it looks likethat it will swallow my application!

Does anyone have a better way or solution to do this (especially around the topic of finding consecutive timeslots)?

+3


source to share


4 answers


Sounds like a fun project. :)

I personally would not model "existing time", i.e. I would not have a background job to create "empty" data.

I would try a model like this:

enter image description here

Where is the user table?

I would not use a common user model for two different types of users. My gut feeling is that they should be different, if not now, the most morose over time. It also makes the model more understandable in my opinion. If there is a login or any authorizer, I would add a User table for that specific data, and rather the service provider and consumer have something to do with this.

Service provider manages availability

The service provider would only need a blank calendar (or similar) that only lists its already installed Availability Service for each service.



Purpose of consumer books

The consumer will search / view / navigate through the availability of the service, for the service

Depending on the business logic, i.e. will the user always schedule the entire specified time slot? Or the consumer can order a preferred time slot. While the reserved slot is within the given time slot available for the Service?

Planning

As such, we only post service availability records when the service provider manages its availability for a specific service. Empty is simply considered inaccessible.

We only post appointment records when a consumer purchases a service based on the availability of the service.

If it is possible so that the consumer can only reserve a portion of the service's availability time interval, I would recommend creating two (or one) new service availability records for the remaining time. Checking the availability of time can be done by comparing the availability of the service with the assignment, but this is not optimal. Better would be to simply query the service availability for a specific service and get an availability graph where no entry would indicate no availability.

There are many here, depending on your needs and the business logic requested. But I hope this helps with some inspiration and ideas.

+11


source


I would have one model for each availability period. Each period has start_time

and end_time

. They can be easily checked to be no more than 6 months in advance and you can check if the appointment is appropriate. Your time slot does not have to belong to the destination as such; the appointment will simply have the time and the service provider, and the specified service provider availability will change to reflect the booked appointment.

class AvailabilityPeriod < ActiveRecord::Base 
    belongs_to :service_provider, :class_name => "User"
    validates :end_time, :inclusion => { :in => Time.now..(Time.now + 6.months) }

end

      

For example, you can find all the possibilities for a given service and provider like this:

duration = @service.duration
available_times = @provider.availability_periods.where (end_time - start_time > duration)

      

Booking an appointment is a little tricky. You need to split / shorten the availability period. For example, let's say a supplier has the following availability:



May 30 12:00 - 18:00

Appointment booked for May 30th 14:00 - 16:00

The old availability must be removed and replaced with two new ones: May 30 12:00 - 14:00 May 30 16:00 - 18:00

But this is pretty easy to do in a model method.

+6


source


I like jpriebe's solution, although I would suggest a small change to test: use (Date.today + 6.months).end_of_day

for the extreme end of the range.

The reason for my suggestion is to make the system a little more user-friendly. If you have used Time.now

and the user wants to create an availability ending ending at 4:00 pm, but they are still a little early in the morning (say around 10:15 am), 4pm would be out of range. To create the AccessPeriod, they had to remember to come back later - and they can forget / take the lasagna out of the oven / insert a distraction here.

Admittedly, there really is only one possible time this scenario could occur and if the user tries to create an AccessPeriod exactly 6 months in advance (e.g. May 27 => Nov 27). In most cases, I'm pretty sure most users won't set an accessibility option, which is far ahead. However, the use .end_of_day

extends the valid time interval to the end of the corresponding day.

+1


source


Instead of randomly segmenting time slots, especially if multiple assignments can be exactly one 30-minute interval, create assignments with arbitrary start and stop times. Assuming the appointments won't last for several days, you might have a daily pattern that has multiple assignments. You will have to handle the overlap computations programmatically, but you won’t beat your database to death to do this, you only need to join Day, Appointment, and Providers and then run the computations to find your open slots. Appointments can be 5 minutes or 6 hours. Never mind.

0


source







All Articles