Class: LiveEvent
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- LiveEvent
- Includes:
- Models::Auditable
- Defined in:
- app/models/live_event.rb
Overview
Live webinars and events with caching for homepage and globals bootstrap.
Constant Summary collapse
- HOMEPAGE_EVENTS_LIMIT =
Homepage carousel: next N upcoming events of any type, soonest first.
12- LIVE_CACHE_KEY =
Key used for live cache.
'live_event/current_live'.freeze
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Delegated Instance Attributes collapse
-
#clear_live_cache ⇒ Object
Alias for Class#clear_live_cache.
-
#flush_edge_cache ⇒ Object
Alias for Class#flush_edge_cache.
Class Method Summary collapse
-
.by_category ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are by category.
- .cached_urls ⇒ Array<String>
- .clear_live_cache ⇒ void
- .flush_edge_cache ⇒ void
-
.future_or_current_events ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are future or current events.
- .get_live ⇒ LiveEvent?
- .history_at(date) ⇒ ActiveRecord::Relation<LiveEvent>
-
.homepage_events_cache_key ⇒ String
Efficient cache key for homepage events using Rails 7 built-in collection caching cache_key_with_version runs a single SELECT COUNT(*), MAX(updated_at) query.
-
.next_for_homepage ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next for homepage.
-
.next_homepage_event_air_date ⇒ ActiveSupport::TimeWithZone?
Efficient next air date check for cache expiry calculation.
-
.next_non_webinars ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next non webinars.
-
.next_non_webinars_all ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next non webinars all.
-
.next_non_webinars_all_expanded ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next non webinars all expanded.
-
.next_webinars ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next webinars.
-
.next_webinars_all ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next webinars all.
- .on_deck ⇒ LiveEvent?
- .ransackable_scopes(_auth_object = nil) ⇒ Array<Symbol>
Instance Method Summary collapse
-
#duration_label ⇒ String
Human-readable duration label for display.
-
#duration_minutes ⇒ Integer
Returns the event duration in minutes.
-
#to_event_schema ⇒ SchemaDotOrg::Event
Build a schema.org Event for this live event.
- #to_s ⇒ String
-
#toggle_live ⇒ Boolean
Toggles this event as the single live event.
Methods included from Models::Auditable
#all_skipped_columns, #audit_reference_data, #creator, #should_not_save_version, #stamp_record, #updater
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransortable_attributes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Class Method Details
.by_category ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are by category. Active Record Scope
35 36 37 38 39 40 41 42 43 44 |
# File 'app/models/live_event.rb', line 35 scope :by_category, ->(category) { case category when 'webinar' where(is_webinar: true) when 'event' where(is_webinar: false) else all end } |
.cached_urls ⇒ Array<String>
160 161 162 163 164 |
# File 'app/models/live_event.rb', line 160 def self.cached_urls urls = LocaleUtility.service_locales.map { |locale| "#{WEB_URL}/#{locale}/showcases" } urls += SiteMap.where(resource_type: name).map(&:url) urls end |
.clear_live_cache ⇒ void
This method returns an undefined value.
155 156 157 |
# File 'app/models/live_event.rb', line 155 def self.clear_live_cache Rails.cache.delete(LIVE_CACHE_KEY) end |
.flush_edge_cache ⇒ void
This method returns an undefined value.
167 168 169 170 |
# File 'app/models/live_event.rb', line 167 def self.flush_edge_cache urls = cached_urls EdgeCacheWorker.perform_async('urls' => urls) if urls.present? end |
.future_or_current_events ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are future or current events. Active Record Scope
34 |
# File 'app/models/live_event.rb', line 34 scope :future_or_current_events, ->(apply_filter = true) { apply_filter.to_b ? where(LiveEvent[:air_date].gt(1.hour.ago)) : all } |
.get_live ⇒ LiveEvent?
147 148 149 150 151 |
# File 'app/models/live_event.rb', line 147 def self.get_live Rails.cache.fetch(LIVE_CACHE_KEY, expires_in: 5.minutes) do where(is_live: true).first end end |
.history_at(date) ⇒ ActiveRecord::Relation<LiveEvent>
84 85 86 87 88 |
# File 'app/models/live_event.rb', line 84 def self.history_at(date) start_date = date - 1.week end_date = date + 1.week where(air_date: start_date..end_date) end |
.homepage_events_cache_key ⇒ String
Efficient cache key for homepage events using Rails 7 built-in collection caching
cache_key_with_version runs a single SELECT COUNT(*), MAX(updated_at) query
59 60 61 |
# File 'app/models/live_event.rb', line 59 def self.homepage_events_cache_key "homepage_events/v5/#{next_for_homepage.cache_key_with_version}" end |
.next_for_homepage ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next for homepage. Active Record Scope
52 |
# File 'app/models/live_event.rb', line 52 scope :next_for_homepage, -> { future_or_current_events.order(:air_date).limit(HOMEPAGE_EVENTS_LIMIT) } |
.next_homepage_event_air_date ⇒ ActiveSupport::TimeWithZone?
Efficient next air date check for cache expiry calculation
65 66 67 |
# File 'app/models/live_event.rb', line 65 def self.next_homepage_event_air_date future_or_current_events.minimum(:air_date) end |
.next_non_webinars ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next non webinars. Active Record Scope
46 |
# File 'app/models/live_event.rb', line 46 scope :next_non_webinars, -> { where(is_webinar: false).future_or_current_events.order(:air_date).limit(3) } |
.next_non_webinars_all ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next non webinars all. Active Record Scope
48 |
# File 'app/models/live_event.rb', line 48 scope :next_non_webinars_all, -> { where(is_webinar: false).future_or_current_events.order(:air_date).limit(10) } |
.next_non_webinars_all_expanded ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next non webinars all expanded. Active Record Scope
49 |
# File 'app/models/live_event.rb', line 49 scope :next_non_webinars_all_expanded, -> { where(is_webinar: false).future_or_current_events.order(:air_date).offset(10).limit(30) } |
.next_webinars ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next webinars. Active Record Scope
45 |
# File 'app/models/live_event.rb', line 45 scope :next_webinars, -> { where(is_webinar: true).future_or_current_events.order(:air_date).limit(1) } |
.next_webinars_all ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are next webinars all. Active Record Scope
47 |
# File 'app/models/live_event.rb', line 47 scope :next_webinars_all, -> { where(is_webinar: true).future_or_current_events.order(:air_date) } |
.on_deck ⇒ LiveEvent?
76 77 78 79 80 |
# File 'app/models/live_event.rb', line 76 def self.on_deck range = history_at(Time.current) sorted_by_proximity = range.sort_by { |event| (Time.current - event.air_date).abs } sorted_by_proximity.first end |
.ransackable_scopes(_auth_object = nil) ⇒ Array<Symbol>
71 72 73 |
# File 'app/models/live_event.rb', line 71 def self.ransackable_scopes(_auth_object = nil) %i[by_category future_or_current_events] end |
Instance Method Details
#clear_live_cache ⇒ Object
Alias for Class#clear_live_cache
174 |
# File 'app/models/live_event.rb', line 174 delegate :clear_live_cache, to: :class |
#duration_label ⇒ String
Human-readable duration label for display. Derived from duration_minutes.
99 100 101 102 |
# File 'app/models/live_event.rb', line 99 def duration_label mins = duration_minutes mins >= 45 ? "#{mins - 15}–#{mins} min" : "Under #{mins} min" end |
#duration_minutes ⇒ Integer
Returns the event duration in minutes.
When a duration_minutes column is added via migration, update this method to read it.
93 94 95 |
# File 'app/models/live_event.rb', line 93 def duration_minutes is_webinar? ? 60 : 15 end |
#flush_edge_cache ⇒ Object
Alias for Class#flush_edge_cache
172 |
# File 'app/models/live_event.rb', line 172 delegate :flush_edge_cache, to: :class |
#to_event_schema ⇒ SchemaDotOrg::Event
Build a schema.org Event for this live event.
Google rich result: https://developers.google.com/search/docs/appearance/structured-data/event
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'app/models/live_event.rb', line 107 def to_event_schema SchemaDotOrg::Event.new( name: title, startDate: air_date, endDate: air_date + duration_minutes.minutes, eventStatus: 'https://schema.org/EventScheduled', eventAttendanceMode: 'https://schema.org/OnlineEventAttendanceMode', location: SchemaDotOrg::VirtualLocation.new( url: url, name: 'Online via Zoom' ), url: url, organizer: SchemaDotOrg::Organization.new( name: 'WarmlyYours', url: 'https://www.warmlyyours.com' ), offers: SchemaDotOrg::Offer.new( price: '0', priceCurrency: 'USD', url: url, availability: 'https://schema.org/InStock' ) ) end |
#to_s ⇒ String
133 134 135 |
# File 'app/models/live_event.rb', line 133 def to_s "#{title} #{air_date.to_fs(:crm_date_only)} [#{session_id}]" end |
#toggle_live ⇒ Boolean
Toggles this event as the single live event.
139 140 141 142 143 |
# File 'app/models/live_event.rb', line 139 def toggle_live self.class.clear_live_cache LiveEvent.update_all(is_live: false) toggle!(:is_live) end |