日历中的重复事件 – Rails

我正在寻找模拟重复事件的最佳方法。 我正在使用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 

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

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

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

RecurrencePeriod从其base_event开始的日期开始。 另外,我假设Event的employee_id指的是创建该事件的员工。 RecurrencePeriod也将属于创建base_event的员工。

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

  • WeeklyRecurrence
    • Integer week_between_recurrences
    • RecurrencePeriod recurrence_period belongs_to :recurrence, :polymorphic=>true

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

Ice cube库似乎可能对计算重复次数很有用。 如果上面的WeeklyRecurrence不够强大,您可能只想在模型中存储Ice cube Schedule对象,替换WeeklyRecurrence 。 要在模型中存储Schedule对象,请将其另存为属性“schedule”,将serialize :schedule放入模型定义中,并在数据库中生成文本列“schedule”。

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

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

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

当用户编辑重复时,他们应该可以选择修改所有实例,所有将来发生的事件或仅修改该事件。 如果它们修改了所有实例,请修改RecurrencePeriod的base_event。 如果它们修改了将来发生的所有事件,请使用您应该在RecurrencePeriod上实现的方法,该方法将自身拆分为特定日期任一侧的两个RecurrencePeriod ,然后将更改保存到第二个周期。 如果它们仅修改该事件,则在它们覆盖的时间创建一个OccurrenceOverride ,并将更改保存到覆盖的replacement_event。

当用户说某个事件现在应该在可预见的将来每两周重复一次时,您应该使用该事件创建一个新的RecurrencePeriod作为base_event和一个nil end_date。 它的重复发生应该是一个新的WeeklyRecurrence ,周期为____sturrent = 2,它应该没有OccurrenceOverride s。

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

 # 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 

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

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

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

当然,如果您有无限期重复的事件,您将希望限制未来您希望生成这些事件的距离,并使用自动rake任务来清理旧的rake任务并生成明年左右的事件。

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

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

只是一个不受欢迎的意见,或许是评论者会指出我目前没有想到的问题:

我会创建一个具有has_many :eventsRecurringEvent模型(或任何你想称之为的模型)。

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

RecurringEvent模型可以具有开始日期和模式,并且它最初可以使用此模式来创建单个发生的事件。 然后,对于作为定期系列的一部分的任何事件,您可以修改或删除该个别事件,但您也可以“重新生成系列”,删除系列中的所有事件(或系列中的所有未来事件)并基于此重建它们一种新模式,例如将会议从“每个星期二”移到“每个星期四”。

关于这一点的另一个好处是你可以创建一个反复出现的事件的一览表,这可能会让你对人们的主要义务有一个很好的洞察力。

就像我说的那样,我不知道如何接近它,但这只是一个想法而我没有建造这样的东西所以我不知道这个方法中是否有任何大问题我是提示。

祝你好运,请发布你最终做的事情!

我对Rails很新,你的解决方案听起来很有趣。 要创建计划和相关事件,您是否在事件模型中使用条件回调?

在我的情况下,用户将能够创建事件,每周复活或不复制。 所以我在考虑事件模型中的重复布尔字段。 所以我猜你会有第一个回调来创建时间表:

 before_save :create_weekly_schedule, if: :recurring 

基本上是第二个创建出现的:

 after_save :create_occurences_if_recurring def create_occurences_if_recurring schedules.each do |sched| occurences.create(start_date: sched.start_time, end_date: sched.end_time) end end 

这听起来合乎逻辑吗? 谢谢

Interesting Posts