我寻找到周期性事件模型的最佳途径。 我使用fullcalendar显示事件。 但我想重复事件在轨道后端最好的处理。
我已经看了看其他的问题和现有的示例代码,但我没有找到任何这适合。
它应该表现得像谷歌日历相似。 因此,它应该可以删除/修改定期事件系列的单个事件 。 但保存在数据库中的事件系列的所有事件似乎效率不高。 此外,它应该是可能的,没有任何复发创建单一事件。
这将是一个很好的模型架构?
我的事件模型,现在看起来像这样( 无需额外的属性 ):
# 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
这是我会怎么建模。 我还没有使用谷歌日历了,所以我立足的功能关闭的iCal中的重复事件。
所有型号都应该有平时的id,created_at,性能的updated_at。 列出的是自定义属性。 如果该属性是另一种模式,你会实现它的关联,如has_one
或belongs_to
。
-
RecurrencePeriod
-
Event
base_event# has_one :base_event, :class_name'Event'
-
Time
END_DATE#可以是零,如果它永远复发 -
WeeklyRecurrence
复发# has_one :recurrence, :as=>:recurrence
-
Array[OccurrenceOverride]
重写# has_many :overrides, :class_name=>'OccurrenceOverride'
该RecurrencePeriod
开始在其base_event开始的日期。 另外,我认为一个Event
的雇员标识是指创建该事件的员工。 一个RecurrencePeriod
也将属于创建该base_event员工。
该模型取决于你想如何灵活地能够指定复发。 你要支持“周二和周四每两个星期从上午10点至11点和下午2点到下午3点”或只是“每周重复”? 下面是只支持“每周重复”,“每两周重复”等模型; 如果你需要,你可以扩展它。
-
WeeklyRecurrence
-
Integer
weeks_between_recurrences -
RecurrencePeriod
RECURRENCE_PERIOD# belongs_to :recurrence, :polymorphic=>true
我使用多态关联这里,因为我觉得如果你想不止一种类型的复发,这样他们都可能是有用的WeeklyRecurrence
和DailyRecurrence
。 但我不知道他们是到模型的正确方法,因此,如果他们变成没有要,只使用has_one :weekly_recurrence
和belongs_to :recurrence_period
代替。
该冰块库好像它可能是计算复发有用。 如果WeeklyRecurrence
以上是不够强大,你可能只是想储存冰块Schedule
对象模型,代替WeeklyRecurrence
。 要存储一个Schedule
对象模型,将其保存为一个属性“时间表”,把serialize :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
,创建一个方法generate_events_in_range(start_date, end_date)
生成Event
S,不要在数据库中保存,但只传递给视图,以便它可以显示它们。
当用户编辑再次发生,他们应该有修改出现的所有选项,所有将来重复,还是只是事件。 如果他们修改所有实例,修改RecurrencePeriod
的base_event。 如果他们修改所有将来重复,使用你应该实现一个方法RecurrencePeriod
本身分裂成两个RecurrencePeriod
S于某一特定日期的两侧,然后保存更改只是第2期。 如果他们只修改该事件,创造一个OccurrenceOverride
对于他们压倒一切的时间,并保存更改覆盖的replacement_event。
当用户表示某个事件现在应该每两个星期再次出现在可预见的未来,你应该创建一个新RecurrencePeriod
与该事件为base_event和零END_DATE。 其复发应该是一个新的WeeklyRecurrence
与weeks_between_recurrence = 2,应该没有OccurrenceOverride
秒。
在我来说,我做了这样的事情:
# 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管理出现的计算和存储在出现表的结果。 我第一次尝试没有发生模型的工作,但无论多么先进规则引擎,你将永远有例外,所以存储的出现在自己的模式为您提供了灵活性。
有一个发生模式使得它更容易显示在日历或日期搜索过滤器的事件,你只需要查询事件,然后显示相关的事件的数据,而不是聚集在一个给定的日期范围内的所有事件,然后具有过滤掉其中的时间表(S)不匹配的事件。
你也可以标示为取消或修改(设置为false时生成的属性,以便编辑ice_cube时间表时,它不会被清理......或任何您的业务需求是)一个事件发生
当然,如果你有无限重复的事件,你会希望限制要多远的未来产生并使用自动耙任务清理旧的,并产生出现在未来一年左右的事件。
到目前为止,这种模式效果很好我。
另外,还要看看recurring_select宝石这是一个漂亮整洁ice_cube形式输入。
只是把我的头顶部的意见,或许会comenters指出一个问题,我没有在时刻想着:
我会做一个RecurringEvent
模型(或任何你想将它命名)是has_many :events
。
假设每个事件是由员工创造(根据你的笔记),然后RecurringEvent
也belong_to :employee
。 然后,您可以建立一个has_many :through
关系,其中一个员工都有许多事件,有许多重复的事件。
该RecurringEvent模型可以有一个起始日期和模式,它最初可以用这种模式来创建个人发生的历史事件。 然后是重复系列的一部分,你可以修改或删除单个次数,但你也可以“再生系列”,删除系列中的所有事件(或系列中的所有未来事件)和重建任何情况下他们根据一种新的模式,所以实例移动从“每周二”本次会议“逢星期四”。
一个其他类型的这个好处是你可以创建重复事件,这可能会给你一些很好的洞察人的主要义务的,在一览列表。
就像我说的,把我的头顶部这就是我会接近它,但是这仅仅是一个想法,我还没有建立这样的事情,所以我不知道是否有我的办法有什么大陷阱提示。
祝你好运,请发表你最终做!
我米很新的Rails的,您的解决方案听起来很有趣。 要创建的时间表和相关的出现次数,你使用的事件模型conditionnal回调?
在我的情况下,用户将能够创建活动,每周定期与否。 所以我想在事件模型重复布尔字段。 所以我想你会第一回调创建时间表:
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
这听起来逻辑与您的解决方案? 谢谢