在Rails建立预约系统

我希望建立一个具有以下特征的预约预约应用程序: – 用户可以是服务提供商或买家 – 服务提供商设置他们的可用性(但只能提前6个月设置他们的可用性) – 然后买家可以预约约会在这些可用性上 – 根据服务类型,每次预约需要不同的时间 – 根据买家选择的预约,根据服务需要多长时间显示不同的可用性集

我构建的内容如下: – TimeSlot模型,我根据start_timeend_time属性创建了许多通用的30分钟时隙。 为了使这些时间段延长到未来6个月,我每天都有一个后台工作,创造了所有必要的新时段

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

UserTimeSlots模型,基本上代表服务提供商可以设置的可用性。 因此,当他们创建user_time_slot时,他们基本上是说他们当时可用。

 class UserTimeSlot  "User" belongs_to :appointment end 

– 具有许多user_time_slots的Appointment模型。 它有很多,因为约会属于需要一定时间(服务的time_required属性)的服务,并且它可能跨越多个连续的 user_time_slots。

 class Appointment  "User" belongs_to :service_provider, :class_name => "User" belongs_to :service end 

– 具有许多约会并且属于创建该服务的服务提供商的服务模型。

 class Service  "User" end 

这个领域模型有效; 但是,我想知道是否有更好的方法来做到这一点,因为以下内容:

  • 使用后台工作每天在我的后端创建TimeSlot记录对我来说似乎有点笨拙 – TimeSlots的唯一目的是有一个开始和结束时间然后被关联。

    • 一旦用户(买方)选择了他们想要的服务,我不确定如何有效地找到连续的x个user_time_slots,因此可用于预约(例如,如果我有30分钟的时间间隔并且用户选择将花费3个小时的约会,我将不得不找到6个连续的时间段)。 例如,如果用户点击服务的实例,我将不得不1)获得该服务所需的时间(很容易做到)和2)我必须找到所有用户的user_time_slots并收集他们的关联time_slots,然后将每个时隙的开始和结束时间相互比较以找到连续的时间。 这对我来说似乎太过迭代了,似乎这会让我的应用程序陷入困境!

有没有人有更好的方法或解决方案来做到这一点(特别是围绕找到连续时间段的主题)?

看起来像一个有趣的项目。 🙂

我个人不会模拟“现有时间”,即我没有后台工作创建“空”数据。

我会尝试这样的模型:

在此处输入图像描述

用户表在哪里?

我不会为两种不同的用户类型使用共享用户模型。 我的直觉是,他们需要与众不同,如果不是现在,他们需要与时俱进。 在我看来,它也使模型更加清晰。 如果有登录或任何身份validation,我会为该特定数据添加一个User表,而服务提供者Consumer与此有一些关系。

服务提供商管理可用性

服务提供商只需要一个空的日历(或类似的),仅列出她已经输入的每个服务的 服务可用性

消费者预约

消费者将按服务搜索/浏览/导航服务可用性

根据业务逻辑,即消费者是否总是安排整个定义的时间段? 或者消费者可以预订一个首选时段。 只要预订的时段在给定服务的可用时段内?

调度

因此,我们仅在服务提供商管理其特定服务的可用性时放入服务可用性记录。 空被简单地认为不可用。

我们仅在消费者根据服务可用性预订服务时放入约会记录。

如果消费者只能预订服务可用性时隙的一部分,我建议在剩余的时间内创建两个(或一个)新的服务可用性记录。 检查时间是否可用可以通过比较服务可用性约会来完成,但这不是最佳的。 更好的方法是只查询特定服务的服务可用性并获得可用性计划,其中没有记录意味着没有可用性。

这里有很多ifs,具体取决于您的特定需求和请求的业务逻辑。 但我希望这有助于一些灵感和想法。

对于每个可用期,我会有一个模型。 每个句点都有一个start_timeend_time 。 它们可以在不超过6个月的时间内轻松validation,您可以检查预约是否合适。 您的时间段不需要属于预约; 约会将只有一个时间和服务提供商,并且所述服务提供商的可用性将改变以反映预订的约会。

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

例如,您可以找到给定服务和提供商的所有可能的可用性,如下所示:

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

预约会有点棘手。 您需要拆分/缩短可用期。 例如,假设提供商具有以下可用性:

5月30日12:00至18:00

预约时间为5月30日14:00至16:00

旧的可用性需要删除,并由两个新的可用性替换: 5月30日12:00 – 14月5月30日16:00 – 18:00

但是在模型方法中这很容易做到。

我喜欢jpriebe的解决方案,但我建议稍微更改validation:使用(Date.today + 6.months).end_of_day作为范围的最末端。

我的建议的原因是使系统更加用户友好。 如果您使用Time.now ,并且用户想要创建一个在下午4点结束的AvailabilityPeriod,但它仍然处于早晨(例如,大约上午10:15),下午4点将超出范围。 要创建AvailabilityPeriod,他们必须记得稍后回来 – 他们可能会忘记/正在将烤宽面条从烤箱中取出/插入分散注意力。

不可否认,实际上只有一个可能出现这种情况的时间,那就是用户正在尝试提前6个月创建一个AvailabilityPeriod(例如,5月27日=> 11月27日)。 大多数时候,我确信大多数用户都不会提前设置可用性。 尽管如此,使用.end_of_day会将可接受的时间范围延长到适当的一天结束时间。

而不是任意分割时隙,特别是如果几乎没有约会可能是一个30分钟的间隔,创建具有任意开始和停止时间的约会。 假设约会不会持续数天,您可以拥有一个具有多个约会的Day模型。 您必须以编程方式处理重叠计算,但是您不会将数据库击败为死,您​​只需要加入Day,Appointment和Providers,然后运行计算以找到您的空位。 预约可以是5分钟或6个小时。 无所谓。