使用Ruby on Rails进行时间可用性比较

时间:2011-07-08 01:48:22

标签: ruby-on-rails ruby algorithm ruby-on-rails-3 database-design

我希望有一个多个对象的可用性表,并进行比较。例如,租房者会搜索租赁单位,该单位可在星期一下午1点开始提供。

为了做到这一点,我想我会把这一周分成30分钟的时间段并给每个时段一个ID。然后日期范围将搜索相应的时间段ID。

但是,然后我需要5040条记录来跟踪每个时间段,而且我对于手动维护它并不太兴奋(在Ruby中我不知道如何去做)。是否有一个更优雅的方法,通过使用日期时间,或一些Rails插件,将做我想要的东西,但更容易?

关键要求是它必须比较多个分开的时间块。

编辑:如果可以通过比较多个时间段来查看最佳匹配,那将是一个奖励。例如,如果我想在星期一,星期三和星期五租用摄像机,并且一天有一台摄像机可用,而另一台摄像机只有两天可用,我希望能够对摄像机进行比较和排序。最佳匹配的基础。

2 个答案:

答案 0 :(得分:5)

您不需要拥有如此复杂的模型。您只需要一张表格,其中显示出租单位可用的时间块,换句话说,就是每个出租单位预订时间的表格。例如:

create table BOOKING 
( rental_unit_id  int 
, start_datetime  date
, end_datetime    date
)

现在,如果您想获得可用于整个给定时间段的租赁单元列表,请将@Arrive称为@Depart,那么您所要做的就是运行如下查询:

select R.rental_unit_id -- (and anything else you want)
from RENTAL_UNIT R
where not exists ( select B.rental_unit_id
                   from BOOKING B
                   where B.rental_unit_id = R.rental_unit_id
                     and end_datetime > @Arrive
                     and start_datetime < @Depart )

此查询说明了一个租赁单元列表,其中没有预订与感兴趣的搜索周期重叠(从@Aririve到@Depart)。请注意,您可以使用&lt; = @Depart,具体取决于您是否希望在预订期间拥有包容性或独占端点。

编辑:处理多个可用性块

@OP增加了对多个可用性块的要求。如果您在多天内租用设备,那么@Arrive和@Depart就会在不同的日期发生。如果在@ OP的例子中,多天在中间有间隙 - 可能是设备返回并可以租给其他人 - 那么你只需添加额外的where not exists子句 - 每个独立块一个期望的可用性。只需“和”他们在一起,您就会找到所有所需时间段中可用的出租单位。更好或更差的比赛的概念并不真正适用。租赁单位可用或不可用。

答案 1 :(得分:2)

我想说你的时间段应该是以下型号:

TimeSlot
   rental_id : int -> foreign key to your rental table (housing, whatever)
   start_time  : time
   end_time    : time
   day_of_week : int 1-7

然后在两次可用性之间进行搜索:(我们称之为AVAILABLE_SLOTS)

(
  (wanted_start_time >= TimeSlotTable.start_time && wanted_start_time <= TimeSlotTable.end_time)  OR
  (wanted_end_time >= TimeSlotTable.start_time && wanted_end_time <= TimeSlotTable.end_time) 
) 
AND Optionally:
( wanted_day_of_week  = TimeSlotTable.day_of_week)

其中TimeSlotTable是表的名称。

然后,如果您真的希望从查询中获得更多粒度,则可以拥有异常表。也就是说,租赁所有者指示他们在特定日期是否不可用的表格,这将要求UI除了要求时还要求日期。 (让我们称之为例外)

ExceptionTimeSlot
   rental_id : int -> foreign key to your rental table (housing, whatever)
   date : date

和查询:

( wanted_date  = ExceptionTimeSlotTable.date)

最后,您需要在AVAILABLE_TIMESLOTS中但不在EXCEPTIONS中的rental_ids。

整个事情感觉就像一个活动日历,所以你可以拿起一个偶数日历并根据你的目的进行自定义,并调用事件时间段。