28

定期的なイベントをモデル化するための最良の方法を探しています。フルカレンダーを使用してイベントを表示しています。しかし、繰り返し発生するイベントは、レールバックエンドで処理するのが最適だと思います。

他の質問や既存のサンプルコードをすでに調べましたが、適切なものは見つかりませんでした。

グーグルカレンダーのように振る舞うはずです。したがって、定期的なイベントシリーズの単一のイベントを削除/変更できるはずです。ただし、一連のイベントのすべてのイベントをデータベースに保存するのは非効率的です。また、再発することなく単一のイベントを作成できるはずです。

良いモデルアーキテクチャは何でしょうか?

私のイベントモデルは現在、次のようになっています(追加の属性なし):

# 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
4

4 に答える 4

42

これが私がこれをモデル化する方法です。私はGoogleカレンダーをあまり使用していないので、iCalの定期的なイベントに基づいて機能を使用しています。

すべてのモデルには、通常のid、created_at、updated_atプロパティが必要です。リストされているのはカスタムプロパティです。プロパティが別のモデルである場合は、has_oneまたはなどの関連付けを実装しますbelongs_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'

base_eventRecurrencePeriodが開始する日付から開始します。また、Event's employee_idは、そのイベントを作成した従業員を指していると思います。ARecurrencePeriodは、base_eventを作成した従業員にも属します。

モデルは、繰り返しを指定できるようにする柔軟性によって異なります。「火曜日と木曜日は2週間ごとに午前10時から午前11時までと午後2時から午後3時まで」をサポートしますか、それとも単に「毎週繰り返す」をサポートしますか?これは、「毎週繰り返す」、「2週間ごとに繰り返す」などをサポートするモデルです。必要に応じて拡張できます。

  • WeeklyRecurrence
    • Integerweeks_between_recurrences
    • RecurrencePeriodrecurrence_period belongs_to :recurrence, :polymorphic=>true

ここではポリモーフィックな関連付けを使用します。これは、との両方WeeklyRecurrenceなど、複数のタイプの再発が必要な場合に役立つと思うためですDailyRecurrence。しかし、それらがそれをモデル化する正しい方法であるかどうかはわかりません。したがって、そうでないことが判明した場合は、代わりにを使用has_one :weekly_recurrencebelongs_to :recurrence_periodてください。

アイスキューブライブラリは、再発の計算に役立つ可能性があるようです。WeeklyRecurrence上記が十分に強力でない場合は、を置き換えて、モデルにアイスキューブオブジェクトを格納することをお勧めしScheduleます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内のどの再発を置き換えるかを一意に識別します
    • Eventreplace_event has_one :replacement_event, :class_name=>'Event'; その再発が編集される代わりに削除された場合、nilになる可能性があります

イベントの各発生を個別に保存するのではなく、ビューに表示する必要があるときに一時的に生成します。で、sを生成RecurrencePeriodするメソッドを作成します。データベースに保存するのではなく、ビューに渡して表示できるようにします。generate_events_in_range(start_date, end_date)Event

ユーザーが繰り返しを編集するときは、すべての発生、将来のすべての発生、またはそのイベントのみを変更するオプションが必要です。すべてのオカレンスを変更する場合は、RecurrencePeriod'sbase_eventを変更します。それらが将来のすべての発生を変更する場合は、特定の日付の両側でRecurrencePeriod2つに分割される、実装する必要のあるメソッドを使用して、変更を2番目の期間だけに保存​​します。RecurrencePeriodそれらがそのイベントのみを変更する場合はOccurrenceOverride、それらがオーバーライドしている時間の間を作成し、オーバーライドのreplacement_eventに変更を保存します。

ユーザーが、特定のイベントが当面の間2週間ごとに繰り返される必要があると言った場合、RecurrencePeriodそのイベントをbase_eventおよびnilend_dateとして新しいものを作成する必要があります。その再発はWeeklyRecurrence、weeks_between_recurrence = 2の新しいものである必要があり、sがない必要がありOccurrenceOverrideます。

于 2012-04-22T08:36:04.657 に答える
6

私の場合、私はこのようなことをしました:

# 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を使用してオカレンスの計算を管理し、結果をオカレンステーブルに保存しました。私は最初にオカレンスモデルなしで作業しようとしましたが、ルールエンジンがどれほど高度であっても、常に例外が発生するため、オカレンスを独自のモデルに保存すると柔軟性が得られます。

オカレンスモデルを使用すると、特定の日付範囲のすべてのイベントを収集してから取得する代わりに、オカレンスをクエリしてから関連するイベントのデータを表示するだけでよいため、カレンダーまたは日付検索フィルターを使用してイベントを表示するのがはるかに簡単になります。スケジュールが一致しないイベントを除外します。

また、イベントの発生にキャンセルのフラグを立てたり、変更したりすることもできます(生成された属性をfalseに設定して、ice_cubeスケジュールの編集時にクリーンアップされないようにします...またはビジネスに必要なものは何でも)

もちろん、イベントが無期限に繰り返される場合は、それらのオカレンスを生成する期間を制限し、自動レーキタスクを使用して古いイベントをクリーンアップし、翌年かそこらのオカレンスを生成する必要があります。

これまでのところ、このパターンは私にとってはかなりうまく機能します。

また、かなりきちんとしたice_cubeフォーム入力であるrecurring_selectgemを見てください。

于 2014-01-30T01:18:00.150 に答える
4

私の頭から離れた意見ですが、おそらくコメンターは私が現時点で考えていない問題を指摘するでしょう:

私はそのRecurringEventモデル(またはあなたがそれを呼びたいもの)を作りますhas_many :events

各イベントが(メモに基づいて)従業員によって作成されたとしましょRecurringEventbelong_to :employeehas_many :through次に、従業員に多くのイベントがあり、多くの定期的なイベントがある関係を構築できます。

RecurringEventモデルには、開始日とパターンを含めることができ、最初はこのパターンを使用して、発生する個々のイベントを作成できます。次に、定期的なシリーズの一部であるイベントで、その個々の発生を変更または削除できますが、「シリーズを再生成」して、シリーズ内のすべてのイベント(またはシリーズ内の将来のすべてのイベント)を削除し、に基づいてそれらを再構築することもできます。新しいパターンなので、たとえば、会議を「毎週火曜日」から「毎週木曜日」に移動します。

これに関するもう1つの優れた点は、定期的なイベントの一覧を一目で確認できることです。これにより、人々の主要な義務についての優れた洞察が得られる可能性があります。

私が言ったように、頭のてっぺんからそれが私がそれにアプローチする方法ですが、これは単なるアイデアであり、私はそのようなものを構築していないので、私がしているアプローチに大きな落とし穴があるかどうかわかりません提案します。

頑張って、あなたがやったことを投稿してください!

于 2012-04-15T02:59:13.400 に答える
-1

私はRailsを初めて使用しますが、あなたのソリューションは面白そうです。スケジュールと関連するオカレンスを作成するために、イベントモデルで条件付きコールバックを使用しますか?

私の場合、ユーザーは毎週定期的かどうかに関係なく、イベントを作成できます。そこで、イベントモデルで繰り返し発生するブールフィールドについて考えていました。したがって、スケジュールを作成するための最初のコールバックがあると思います。

before_save :create_weekly_schedule, if: :recurring

そして基本的にオカレンスを作成するための2番目のもの:

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

これはあなたのソリューションにとって論理的に聞こえますか?どうも

于 2014-05-16T23:07:57.300 に答える