日历中的重复事件 - Rails

Ben*_*Ben 27 calendar ruby-on-rails fullcalendar ruby-on-rails-3 recurring-events

我正在寻找模拟重复事件的最佳方法.我正在使用fullcalendar来显示事件.但我想重复发生的事件最好在rails后端处理.

我已经查看了其他问题和现有的示例代码,但我找不到任何合适的东西.

它应该像谷歌日历一样.因此应该可以删除/修改周期性事件系列的单个事件.但是在数据库中保存事件系列的所有事件似乎效率低下.此外,应该可以创建单个事件而不会再次出现.

什么是好的模型架构?

我的事件模型现在看起来像那样(没有其他属性):

# Table name: events
#
#  id              :integer         not null, primary key
#  employee_id     :integer
#  created_at      :datetime
#  updated_at      :datetime
#  starts_at       :datetime
#  ends_at         :datetime
#

class Event < ActiveRecord::Base
  attr_accessible :starts_at, :ends_at
end
Run Code Online (Sandbox Code Playgroud)

Ror*_*ane 40

以下是我对此进行建模的方法.我没有太多使用谷歌日历,所以我的功能基于iCal的重复活动.

所有模型都应具有通常的id,created_at,updated_at属性.列出的是自定义属性.如果属性是另一个模型,您将实现一个关联,如has_onebelongs_to.

  • RecurrencePeriod
    • Eventbase_event #has_one :base_event, :class_name'Event'
    • Timeend_date #可能是nil,如果它永远重复
    • WeeklyRecurrence复发#has_one :recurrence, :as=>:recurrence
    • Array[OccurrenceOverride]覆盖#has_many :overrides, :class_name=>'OccurrenceOverride'

RecurrencePeriod在其base_event开始之日起开始.另外,我假设一个Eventemployee_id指的是创建该事件的员工.A RecurrencePeriod也属于创建base_event的员工.

该模型取决于您希望如何灵活地指定重现.您是否会支持"每两周一次,周二和周四上午10点到上午11点以及下午2点到下午3点",或者只是"每周重复一次"?这是一个只支持"每周重复","每两周重复一次"等的模型; 如果需要,你可以扩展它.

  • WeeklyRecurrence
    • Integer weeks_between_recurrences
    • RecurrencePeriodrecurrence_period #belongs_to :recurrence, :polymorphic=>true

我在这里使用多态关联,因为我认为如果你想要多种类型的重复,它们可能是有用的,例如,WeeklyRecurrenceDailyRecurrence.但是我不确定它们是否是正确的模型,所以如果结果不是这样,那就用has_one :weekly_recurrencebelongs_to :recurrence_period不是.

冰块库好像它可能是计算复发有用.如果WeeklyRecurrence上面的功能不够强大,您可能只想Schedule在模型中存储Ice cube 对象,替换WeeklyRecurrence.要将Schedule对象存储在模型中,请将其另存为属性"schedule",放入serialize :schedule模型定义中,并在数据库中生成文本列"schedule".

OccurrenceOverride 处理正在编辑的重复事件的单个实例的情况.

  • OccurrenceOverride
    • RecurrencePeriodrecurrence_period_to_override #belongs_to :recurrence_period_to_override, :class_name=>'RecurrencePeriod'
    • Timeoriginal_start_time #唯一标识要在其中替换的RecurrencePeriod中的哪个重复
    • Eventreplacement_event #has_one :replacement_event, :class_name=>'Event'; 如果重复被删除而不是编辑,则可能为零

您可以在需要在视图中显示事件时临时生成事件,而不是单独存储事件的每个事件.在RecurrencePeriod,创建一个generate_events_in_range(start_date, end_date)生成Events 的方法,不是保存在数据库中,而只是传递给视图以便它可以显示它们.

当用户编辑重复时,他们应该可以选择修改所有实例,所有将来发生的事件或仅修改该事件.如果他们修改了所有RecurrencePeriod实例,请修改's base_event.如果他们修改所有将来重复,使用您应该实现一个方法,RecurrencePeriod其将自身分成两个RecurrencePeriodS于某一特定日期的两侧,然后保存更改只是第2期.如果他们仅修改该事件,则创建一个OccurrenceOverride覆盖它们的时间,并将更改保存到覆盖的replacement_event.

当用户表示某个事件现在应该每两个星期再次出现在可预见的未来,你应该创建一个新的RecurrencePeriod与该事件为base_event和零END_DATE.它的重复发生应该是一个新的WeeklyRecurrence,周期为_day_recurrence = 2,它应该没有OccurrenceOverrides.


And*_*rew 6

只是我的一个想法,也许评论者会指出一个我目前没有想到的问题:

我会制作一个RecurringEvent模型(或者任何你想称之为的模型)has_many :events

假设每个事件都是由一名员工创建的(根据您的笔记),那么RecurringEvent也将belong_to :employee. 然后,您可以建立一种has_many :through关系,其中员工有许多事件并且有许多重复事件。

RecurringEvent 模型可以具有开始日期和模式,并且它最初可以使用此模式来创建各个发生的事件。然后,对于属于重复系列的任何事件,您可以修改或删除该单个事件,但您也可以“重新生成系列”,删除系列中的所有事件(或系列中的所有未来事件)并根据新的模式,例如将会议从“每周二”改为“每周四”。

这样做的另一个好处是,您可以创建一个重复事件的概览列表,这可能会让您更好地了解人们的主要义务。

就像我说的,这就是我的处理方法,但这只是一个想法,我还没有构建过类似的东西,所以我不知道我的方法中是否存在任何大问题建议。

祝你好运,请发布你最终做了什么!


Jim*_*Jim 5

在我的情况下,我做了这样的事情:

# Holds most of my event's data; name, description, price ...
class Event < ActiveRecord::Base
  has_many :schedules
  has_many :occurrences
  attr_accessible :started_at, :expired_at # expired_at is optional
end

# Holds my schedule object
class Schedule < ActiveRecord::Base
  belongs_to :event
  attr_accessible :ice_cube_rule # which returns my deserialized ice_cube object
end

# Holds generated or manually created event occurrences 
class Occurrence < ActiveRecord::Base
  belongs_to :event
  attr_accessible :started_at, :expired_at
  attr_accessible :generated # helps me tell which occurrences are out of an ice_cube generated serie
  attr_accessible :canceled_at
end
Run Code Online (Sandbox Code Playgroud)

从那里,我使用ice_cube来管理事件计算并将结果存储在出现表中.我首先尝试在没有Occurrence模型的情况下工作,但无论规则引擎有多先进,您都会有异常,因此将事件存储在自己的模型中会给您灵活性.

拥有一个Occurrence模型可以更容易地在日历或日期搜索过滤器上显示事件,因为您只需要查询事件然后显示相关事件的数据,而不是收集给定日期范围内的所有事件然后拥有过滤掉日程表不匹配的事件.

您还可以将事件发生标记为已取消或将其修改(将生成的属性设置为false,以便在编辑ice_cube计划时不会清除它...或者您的业务需要是什么)

当然,如果你有无限重复的事件,你会希望限制要多远的未来产生并使用自动耙任务清理旧的,并产生出现在未来一年左右的事件.

到目前为止,这种模式对我来说非常有效.

另外,看看recurring_select gem,这是一个非常整洁的ice_cube表单输入.

  • 好贴.通过这种方法对您的想法充满好奇:http://blog.plataformatec.com.br/2010/04/recurring-events看起来与您的相似. (2认同)