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
- LIVE_CACHE_KEY =
'live_event/current_live'.freeze
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
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 ⇒ Object
-
.clear_live_cache ⇒ Object
rubocop:enable Naming/AccessorMethodName.
- .flush_edge_cache ⇒ Object
-
.future_or_current_events ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are future or current events.
-
.get_live ⇒ Object
rubocop:disable Naming/AccessorMethodName.
- .history_at(date) ⇒ Object
-
.homepage_events_cache_key ⇒ Object
Efficient cache key for homepage events using Rails 7 built-in collection caching Each scope's cache_key_with_version runs a single SELECT COUNT(*), MAX(updated_at) query.
-
.next_homepage_event_air_date ⇒ Object
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 ⇒ Object
- .ransackable_scopes(_auth_object = nil) ⇒ Object
Instance Method Summary collapse
-
#duration_label ⇒ Object
Human-readable duration label for display.
-
#duration_minutes ⇒ Object
Returns the event duration in minutes.
-
#to_event_schema ⇒ Object
Build a schema.org Event for this live event.
- #to_s ⇒ Object
-
#toggle_live ⇒ Object
rubocop:disable Rails/SkipsModelValidations.
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::EventPublishable
Class Method Details
.by_category ⇒ ActiveRecord::Relation<LiveEvent>
A relation of LiveEvents that are by category. Active Record Scope
34 35 36 37 38 39 40 41 42 43 |
# File 'app/models/live_event.rb', line 34 scope :by_category, ->(category) { case category when 'webinar' where(is_webinar: true) when 'event' where(is_webinar: false) else all end } |
.cached_urls ⇒ Object
141 142 143 144 145 |
# File 'app/models/live_event.rb', line 141 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 ⇒ Object
rubocop:enable Naming/AccessorMethodName
137 138 139 |
# File 'app/models/live_event.rb', line 137 def self.clear_live_cache Rails.cache.delete(LIVE_CACHE_KEY) end |
.flush_edge_cache ⇒ Object
147 148 149 150 |
# File 'app/models/live_event.rb', line 147 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
33 |
# File 'app/models/live_event.rb', line 33 scope :future_or_current_events, ->(apply_filter = true) { apply_filter.to_b ? where(LiveEvent[:air_date].gt(1.hour.ago)) : all } |
.get_live ⇒ Object
rubocop:disable Naming/AccessorMethodName
130 131 132 133 134 |
# File 'app/models/live_event.rb', line 130 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) ⇒ Object
72 73 74 75 76 |
# File 'app/models/live_event.rb', line 72 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 ⇒ Object
Efficient cache key for homepage events using Rails 7 built-in collection caching
Each scope's cache_key_with_version runs a single SELECT COUNT(*), MAX(updated_at) query
53 54 55 |
# File 'app/models/live_event.rb', line 53 def self.homepage_events_cache_key "homepage_events/v4/#{next_webinars.cache_key_with_version}/#{next_non_webinars.cache_key_with_version}" end |
.next_homepage_event_air_date ⇒ Object
Efficient next air date check for cache expiry calculation
58 59 60 |
# File 'app/models/live_event.rb', line 58 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
45 |
# File 'app/models/live_event.rb', line 45 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
47 |
# File 'app/models/live_event.rb', line 47 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
48 |
# File 'app/models/live_event.rb', line 48 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
44 |
# File 'app/models/live_event.rb', line 44 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
46 |
# File 'app/models/live_event.rb', line 46 scope :next_webinars_all, -> { where(is_webinar: true).future_or_current_events.order(:air_date) } |
.on_deck ⇒ Object
66 67 68 69 70 |
# File 'app/models/live_event.rb', line 66 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) ⇒ Object
62 63 64 |
# File 'app/models/live_event.rb', line 62 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
154 |
# File 'app/models/live_event.rb', line 154 delegate :clear_live_cache, to: :class |
#duration_label ⇒ Object
Human-readable duration label for display. Derived from duration_minutes.
85 86 87 88 |
# File 'app/models/live_event.rb', line 85 def duration_label mins = duration_minutes mins >= 45 ? "#{mins - 15}–#{mins} min" : "Under #{mins} min" end |
#duration_minutes ⇒ Object
Returns the event duration in minutes.
When a duration_minutes column is added via migration, update this method to read it.
80 81 82 |
# File 'app/models/live_event.rb', line 80 def duration_minutes is_webinar? ? 60 : 15 end |
#flush_edge_cache ⇒ Object
Alias for Class#flush_edge_cache
152 |
# File 'app/models/live_event.rb', line 152 delegate :flush_edge_cache, to: :class |
#to_event_schema ⇒ Object
Build a schema.org Event for this live event.
Google rich result: https://developers.google.com/search/docs/appearance/structured-data/event
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'app/models/live_event.rb', line 92 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 ⇒ Object
117 118 119 |
# File 'app/models/live_event.rb', line 117 def to_s "#{title} #{air_date.to_fs(:crm_date_only)} [#{session_id}]" end |
#toggle_live ⇒ Object
rubocop:disable Rails/SkipsModelValidations
122 123 124 125 126 |
# File 'app/models/live_event.rb', line 122 def toggle_live self.class.clear_live_cache LiveEvent.update_all(is_live: false) toggle!(:is_live) end |