这是我将如何建模。我没有太多使用 Google 日历,因此我将功能基于iCal的重复事件。
所有模型都应该具有通常的 id、created_at、updated_at 属性。列出的是自定义属性。如果该属性是另一个模型,您将实现它的关联,例如has_one
or belongs_to
。
RecurrencePeriod
Event
base_event #has_one :base_event, :class_name'Event'
Time
end_date # 可能为 nil,如果它永远重复
WeeklyRecurrence
复发#has_one :recurrence, :as=>:recurrence
Array[OccurrenceOverride]
覆盖#has_many :overrides, :class_name=>'OccurrenceOverride'
RecurrencePeriod
开始于其 base_event 开始的日期。另外,我假设 anEvent
的 employee_id 是指创建该事件的员工。ARecurrencePeriod
也将属于创建 base_event 的员工。
该模型取决于您希望能够灵活地指定重复次数。您是要支持“每周二和周四,从上午 10 点到上午 11 点,从下午 2 点到下午 3 点”还是只支持“每周重复一次”?这是一个只支持“每周重复”、“每两周重复”等的模型;如果需要,您可以扩展它。
WeeklyRecurrence
Integer
week_between_recurrences
RecurrencePeriod
复发周期#belongs_to :recurrence, :polymorphic=>true
我在这里使用多态关联,因为我认为如果你想要不止一种类型的重复,它们可能很有用,比如WeeklyRecurrence
和DailyRecurrence
。但我不确定它们是否是建模的正确方法,所以如果结果不是,只需使用has_one :weekly_recurrence
andbelongs_to :recurrence_period
代替。
Ice cube库似乎对计算重复率很有用。如果WeeklyRecurrence
上面的功能不够强大,您可能只想Schedule
在模型中存储一个冰块对象,替换WeeklyRecurrence
. 要将Schedule
对象存储在模型中,将其保存为属性“schedule”,放入serialize :schedule
模型定义,并在数据库中生成文本列“schedule”。
OccurrenceOverride
处理正在编辑的重复事件的单个实例的情况。
OccurrenceOverride
RecurrencePeriod
重复周期到覆盖#belongs_to :recurrence_period_to_override, :class_name=>'RecurrencePeriod'
Time
original_start_time # 唯一标识要替换该 RecurrencePeriod 中的哪个重复
Event
替换事件# has_one :replacement_event, :class_name=>'Event'
; 可能为零,如果该重复被删除而不是编辑
与其单独存储每个事件的发生,不如在需要在视图中显示它们时临时生成它们。在RecurrencePeriod
中,创建一个generate_events_in_range(start_date, end_date)
生成Event
s 的方法,而不是保存在数据库中,而只是传递给视图以便它可以显示它们。
当用户编辑重复时,他们应该可以选择修改所有事件、所有未来事件或仅修改该事件。如果他们修改了所有事件,请修改RecurrencePeriod
'base_event. 如果他们修改了所有未来的事件,请使用您应该实施的方法,在特定日期的两侧RecurrencePeriod
将自身拆分为两个s,然后将更改保存到第二个期间。如果他们仅修改该事件,则为他们覆盖的时间RecurrencePeriod
创建一个,并将更改保存到覆盖的 replacement_event。OccurrenceOverride
当用户说某个事件现在应该在可预见的未来每两周重复一次时,您应该创建一个新RecurrencePeriod
事件,该事件作为 base_event 和一个 nil end_date。它的重复周期应该是一个新WeeklyRecurrence
的,weeks_between_recurrence=2,它应该没有OccurrenceOverride
s。