Ecco come modellerei questo. Non ho usato molto Google Calendar, quindi sto basando la funzionalità sugli eventi ricorrenti di iCal.
Tutti i modelli devono avere le solite proprietà id, created_at, updated_at. Sono elencate le proprietà personalizzate. Se la proprietà è un altro modello, verrà implementata un'associazione come has_one
o belongs_to
.
RecurrencePeriod
Event
base_event # has_one :base_event, :class_name'Event'
Time
data_finale # può essere pari a zero, se si ricorre sempre
WeeklyRecurrence
ricorrenza # has_one :recurrence, :as=>:recurrence
Array[OccurrenceOverride]
override # has_many :overrides, :class_name=>'OccurrenceOverride'
Le RecurrencePeriod
decorre dalla data in cui la sua base_event inizia. Inoltre, suppongo che un employee_id di Event
si riferisca al dipendente che ha creato quell'evento. Un RecurrencePeriod
apparterrà anche al dipendente che ha creato l'evento base_event.
Il modello dipende dalla flessibilità con cui si desidera essere in grado di specificare le ricorrenze. Avete intenzione di sostenere "martedì e giovedì ogni due settimane dalle 10 alle 11 e dalle 14 alle 15" o semplicemente "si ripete settimanalmente"? Ecco un modello che supporta solo "ripetizioni settimanali", "si ripete ogni due settimane", ecc .; puoi espanderlo se necessario.
WeeklyRecurrence
Integer
weeks_between_recurrences
RecurrencePeriod
RECURRENCE_PERIOD # belongs_to :recurrence, :polymorphic=>true
Io uso polymorphic associations qui, perché penso che potrebbe essere utile se si desidera più di un tipo di ricorrenza, tale sia WeeklyRecurrence
e DailyRecurrence
. Ma non sono sicuro che siano il modo corretto di modellarlo, quindi se non risultano essere, usa semplicemente has_one :weekly_recurrence
e belongs_to :recurrence_period
.
La libreria Ice cube sembra essere utile per calcolare le ricorrenze. Se lo WeeklyRecurrence
non è abbastanza potente, potresti semplicemente voler archiviare un oggetto Ice cube Schedule
in un modello, sostituendo WeeklyRecurrence
. Per memorizzare un oggetto Schedule
in un modello, salvarlo come attributo "pianificazione", inserire serialize :schedule
nella definizione del modello e generare una colonna di testo "pianificazione" nel database.
OccurrenceOverride
gestisce il caso di una singola istanza di un evento ricorrente in corso di modifica.
OccurrenceOverride
RecurrencePeriod
recurrence_period_to_override # belongs_to :recurrence_period_to_override, :class_name=>'RecurrencePeriod'
Time
original_start_time # identifica univocamente che recidiva entro che RecurrencePeriod per sostituire
Event
replacement_event # has_one :replacement_event, :class_name=>'Event'
; può essere pari a zero, se che la ricorrenza è stata eliminata, invece di modificare
Invece di memorizzare ogni occorrenza di un evento singolarmente, generare temporaneamente quando si ha bisogno di mostrare loro la vista. In RecurrencePeriod
, creare un metodo generate_events_in_range(start_date, end_date)
che generi Event
s, non per salvare nel database, ma solo per passare alla vista in modo che possa mostrarli.
Quando un utente modifica una ricorrenza, dovrebbe avere la possibilità di modificare tutte le occorrenze, tutte le occorrenze future o solo quell'evento. Se modificano tutte le occorrenze, modifica l'evento base RecurrencePeriod
. Se modificano tutte le occorrenze future, utilizzare un metodo da implementare su RecurrencePeriod
diviso in due RecurrencePeriod
s su entrambi i lati di una determinata data, quindi salvare le modifiche solo nel secondo periodo. Se modificano solo quell'evento, crea un valore OccurrenceOverride
per il tempo in cui stanno eseguendo l'override e salva le modifiche al comando replace_event dell'override.
Quando un utente dice che un determinato evento dovrebbe ripresentarsi ogni due settimane per il prossimo futuro, è necessario creare un nuovo RecurrencePeriod
con quell'evento come base_event e un nil end_date. La sua ricorrenza dovrebbe essere una nuova WeeklyRecurrence
con weeks_between_recurrence = 2 e non dovrebbe avere OccurrenceOverride
s.
Eventuali problemi relativi all'esperienza di non aver persistito un problema anche se non è stato possibile accedervi tramite ID? (prestazioni, complessità, ecc.) – ted
@ted Buona domanda. Non l'ho mai implementato, quindi temo di non sapere se la generazione di occorrenze in base alle esigenze causi problemi. Suppongo che potresti creare una cache per le occorrenze generate, se necessario. Un sistema di memorizzazione nella cache potrebbe utilizzare il fatto che un'occorrenza generata da salvare è concettualmente molto simile a un 'OccurrenceOverride', sebbene non identico. –