我希望建立一个具有以下特征的预约预约应用程序: - 用户可以是服务提供商或买家 - 服务提供商设置其可用性(但最多只能提前6个月设置其可用性) - 然后买家可以根据这些可用性预约 - 根据服务类型,每次预约需要不同的时间 - 根据买家选择的约会,根据服务需要的时间显示不同的可用性集
我建立的是以下内容:
- TimeSlot
模型,我根据start_time
和end_time
属性创建了许多通用的30分钟时段。为了使这些时间段延长到未来6个月,我每天都有一个后台工作,可以创建所有必要的新时段
class TimeSlot < ActiveRecord::Base
has_many :user_time_slots
# ... more methods below
end
- UserTimeSlots
模型,基本上代表服务提供商可以设置的可用性。因此,当他们创建user_time_slot时,他们基本上是说他们当时可用。
class UserTimeSlot < ActiveRecord::Base
belongs_to :time_slot
belongs_to :service_provider, :class_name => "User"
belongs_to :appointment
end
- 具有许多user_time_slots的Appointment
模型。它有很多,因为约会属于服务需要一定的时间(服务的time_required
属性),它可能跨越连续 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
- Service
模型,该模型有许多约会,属于创建该服务的服务提供商。
class Service < ActiveRecord::Base
has_many :appointments
belongs_to :service_provider, :class_name => "User"
end
此域名模型有效;但是,我想知道是否有更好的方法可以做到这一点,原因如下:
使用后台作业每天在我的后端创建TimeSlot记录对我来说似乎有点笨拙 - TimeSlots的唯一目的是拥有开始和结束时间然后关联到。
有没有人有更好的方法或解决方案来执行此操作(特别是围绕查找连续时间段的主题)?
答案 0 :(得分:11)
看起来像一个有趣的项目。 :)
我个人不会模拟“现有时间”,即我没有后台工作创建“空”数据。
我会尝试这样的模型:
用户表在哪里?
我不会为两种不同的用户类型使用共享用户模型。我的直觉是,如果不是现在,他们需要变得不同,随着时间的推移,他们最需要。在我看来,它也使模型更加清晰。如果有登录或任何身份验证,我会为该特定数据添加一个User表,而不是服务提供商和 Consumer 与此有关。
服务提供商管理可用性
服务提供商只需要一个空的日历(或类似的),仅列出她已经输入的服务可用性,每服务。
预约消费者图书
消费者将按服务
搜索/浏览/导航服务可用性根据业务逻辑,即 Consumer 是否总是安排整个定义的时间段?或者 Consumer 可以预订首选时段。只要预订的广告位在给定服务的可用时段内?
计划强>
因此,当服务提供商管理特定服务的可用性时,我们只会将服务可用性记录放入其中。空被简单地认为不可用。
根据服务可用性,我们只在消费者预订服务时放入约会记录。< / p>
如果 Consumer 只能预订服务可用性时间段的一部分,我建议创建两个(或一个)新的服务剩余时间的可用性记录。检查时间是否可用可以通过将服务可用性与约会进行比较来完成,但这不是最佳选择。 更好的方法是只查询特定服务的服务可用性,并获得可用性计划,其中没有记录意味着没有可用性。
这里有很多ifs,具体取决于您的特定需求和请求的业务逻辑。但我希望这有助于一些灵感和想法。
答案 1 :(得分:6)
每个可用期限都有一个模型。每个句点都有start_time
和end_time
。它们可以在不超过6个月的时间内轻松验证,您可以检查预约是否合适。您的时段不需要属于来预约;约会只会有一个时间和服务提供者,并且所述服务提供者的可用性将改变以反映预约的约会。
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:00 5月30日16:00 - 18:00
但这在模型方法中很容易做到。
答案 2 :(得分:1)
我喜欢jpriebe的解决方案,但我建议稍微更改验证:在范围的最末端使用(Date.today + 6.months).end_of_day
。
我建议的原因是使系统更加用户友好。如果您使用Time.now
,并且用户想要创建一个在下午4点结束的AvailabilityPeriod,但它仍然在早上(例如,大约上午10:15),下午4点将超出范围。要创建AvailabilityPeriod,他们必须记得稍后再回来 - 他们可能会忘记/正在将烤宽面条从烤箱中取出/插入分散注意力。
不可否认,实际上只有一个可能出现这种情况的时间,也就是说,如果用户正在尝试提前6个月创建一个可靠的 (例如,5月27日=&gt; 11月27日)。大多数情况下,我确定大多数用户不会提前设置一个AvailabilityPeriod。尽管如此,使用.end_of_day
会将可接受的时间范围延长到适当的一天结束。
答案 3 :(得分:0)
不是任意分割时间段,特别是如果很少有约会可能只是一个30分钟的间隔,则创建具有任意开始和停止时间的约会。假设约会不会持续数天,您可以拥有一个具有约会任命的日模型。您将不得不以编程方式处理重叠计算,但是您不会将数据库击败为死,您只需要加入Day,Appointment和Providers,然后运行计算以找到您的空位。预约可以是5分钟或6小时。没关系。