diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-06-30 19:15:22 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-06-30 19:22:24 +0200 |
| commit | a7a6ad786eeb9f94f7882462bccbdd31e1bb4743 (patch) | |
| tree | ecc0a17db462065b27270f7e593a8244e24c8846 /app | |
| parent | 31ca8e93efa860d73918b57ddddeaedf9917b22d (diff) | |
Phase 1: standalone events, external_url on nodes
- Migration: node_id nullable on events and occurrences, add
title/description/is_primary to events, external_url to nodes
- Existing events marked is_primary: true (were all 1:1 with nodes)
- Node: has_one :event -> has_many :events
- Event: belongs_to :node optional, validates title presence for
standalone events, is_primary uniqueness scoped to node_id,
display_title helper falling back through node title
- Occurrence: belongs_to :node optional, summary falls back to
event.display_title
- nodes_helper: event_information uses events.first (interim; will
be replaced in Phase 3 event UI)
- Tests: fix node.event -> node.events.first in event_test
Diffstat (limited to 'app')
| -rw-r--r-- | app/helpers/nodes_helper.rb | 11 | ||||
| -rw-r--r-- | app/models/event.rb | 29 | ||||
| -rw-r--r-- | app/models/node.rb | 2 | ||||
| -rw-r--r-- | app/models/occurrence.rb | 9 |
4 files changed, 27 insertions, 24 deletions
diff --git a/app/helpers/nodes_helper.rb b/app/helpers/nodes_helper.rb index a054a2e..d88d12a 100644 --- a/app/helpers/nodes_helper.rb +++ b/app/helpers/nodes_helper.rb | |||
| @@ -30,12 +30,13 @@ module NodesHelper | |||
| 30 | end | 30 | end |
| 31 | 31 | ||
| 32 | def event_information | 32 | def event_information |
| 33 | if @node.event | 33 | if @node.events.first |
| 34 | event = @node.events.first | ||
| 34 | safe_join([ | 35 | safe_join([ |
| 35 | "#{@node.event.start_time.to_fs(:db)} - #{@node.event.end_time.to_fs(:db)} > ", | 36 | "#{event.start_time.to_fs(:db)} - #{event.end_time.to_fs(:db)} > ", |
| 36 | link_to('show', event_path(@node.event)), | 37 | link_to('show', event_path(event)), |
| 37 | ' ', | 38 | ' > ', |
| 38 | link_to('edit', edit_event_path(@node.event)) | 39 | link_to('edit', edit_event_path(event)) |
| 39 | ]) | 40 | ]) |
| 40 | else | 41 | else |
| 41 | safe_join([ | 42 | safe_join([ |
diff --git a/app/models/event.rb b/app/models/event.rb index 94a22e3..26c79e4 100644 --- a/app/models/event.rb +++ b/app/models/event.rb | |||
| @@ -1,22 +1,25 @@ | |||
| 1 | class Event < ApplicationRecord | 1 | class Event < ApplicationRecord |
| 2 | 2 | ||
| 3 | # Associations | 3 | belongs_to :node, optional: true |
| 4 | 4 | has_many :occurrences | |
| 5 | has_many :occurrences | 5 | |
| 6 | belongs_to :node | 6 | validates :title, presence: true, unless: -> { node_id.present? } |
| 7 | 7 | validates :is_primary, uniqueness: { scope: :node_id, | |
| 8 | # Callbacks | 8 | message: "only one primary event per node allowed" }, |
| 9 | 9 | if: -> { is_primary? && node_id.present? } | |
| 10 | after_save :generate_occurences | 10 | |
| 11 | 11 | after_save :generate_occurences | |
| 12 | # Instance Methods | 12 | |
| 13 | |||
| 14 | def occurrences_in_range start_time, end_time | 13 | def occurrences_in_range start_time, end_time |
| 15 | self.occurrences.where( | 14 | self.occurrences.where( |
| 16 | "start_time > ? AND end_time < ?", | 15 | "start_time > ? AND end_time < ?", |
| 17 | start_time, end_time | 16 | start_time, end_time |
| 18 | ) | 17 | ) |
| 19 | end | 18 | end |
| 19 | |||
| 20 | def display_title | ||
| 21 | title.presence || node&.head&.title || "Untitled event" | ||
| 22 | end | ||
| 20 | 23 | ||
| 21 | private | 24 | private |
| 22 | def generate_occurences | 25 | def generate_occurences |
diff --git a/app/models/node.rb b/app/models/node.rb index 92ecc12..ba94e2a 100644 --- a/app/models/node.rb +++ b/app/models/node.rb | |||
| @@ -7,7 +7,7 @@ class Node < ApplicationRecord | |||
| 7 | belongs_to :head, :class_name => "Page", :foreign_key => :head_id, :dependent => :destroy, optional: true | 7 | belongs_to :head, :class_name => "Page", :foreign_key => :head_id, :dependent => :destroy, optional: true |
| 8 | belongs_to :draft, :class_name => "Page", :foreign_key => :draft_id, :dependent => :destroy, optional: true | 8 | belongs_to :draft, :class_name => "Page", :foreign_key => :draft_id, :dependent => :destroy, optional: true |
| 9 | has_many :permissions, :dependent => :destroy | 9 | has_many :permissions, :dependent => :destroy |
| 10 | has_one :event, :dependent => :destroy | 10 | has_many :events, :dependent => :destroy |
| 11 | belongs_to :lock_owner, :class_name => "User", :foreign_key => :locking_user_id, optional: true | 11 | belongs_to :lock_owner, :class_name => "User", :foreign_key => :locking_user_id, optional: true |
| 12 | 12 | ||
| 13 | # Callbacks | 13 | # Callbacks |
diff --git a/app/models/occurrence.rb b/app/models/occurrence.rb index 3baf447..143124f 100644 --- a/app/models/occurrence.rb +++ b/app/models/occurrence.rb | |||
| @@ -1,13 +1,12 @@ | |||
| 1 | # TODO Make a gem out of the c wrapper | ||
| 2 | require 'chaos_calendar' | 1 | require 'chaos_calendar' |
| 3 | 2 | ||
| 4 | class Occurrence < ApplicationRecord | 3 | class Occurrence < ApplicationRecord |
| 5 | 4 | ||
| 6 | # Associations | 5 | # Associations |
| 7 | 6 | ||
| 8 | belongs_to :node | 7 | belongs_to :node, optional: true |
| 9 | belongs_to :event | 8 | belongs_to :event |
| 10 | 9 | ||
| 11 | # Class Methods | 10 | # Class Methods |
| 12 | 11 | ||
| 13 | def self.find_in_range start_time, end_time | 12 | def self.find_in_range start_time, end_time |
| @@ -64,7 +63,7 @@ class Occurrence < ApplicationRecord | |||
| 64 | # Instance Methods | 63 | # Instance Methods |
| 65 | 64 | ||
| 66 | def summary | 65 | def summary |
| 67 | node.head.title | 66 | node&.head&.title || event.display_title |
| 68 | end | 67 | end |
| 69 | 68 | ||
| 70 | end | 69 | end |
