Class: LiveEvent

Inherits:
ApplicationRecord show all
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

Class Method Summary collapse

Instance Method Summary collapse

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

#publish_event

Class Method Details

.by_categoryActiveRecord::Relation<LiveEvent>

A relation of LiveEvents that are by category. Active Record Scope

Returns:

See Also:



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_urlsObject



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_cacheObject

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_cacheObject



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_eventsActiveRecord::Relation<LiveEvent>

A relation of LiveEvents that are future or current events. Active Record Scope

Returns:

See Also:



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_liveObject

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_keyObject

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_dateObject

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_webinarsActiveRecord::Relation<LiveEvent>

A relation of LiveEvents that are next non webinars. Active Record Scope

Returns:

See Also:



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_allActiveRecord::Relation<LiveEvent>

A relation of LiveEvents that are next non webinars all. Active Record Scope

Returns:

See Also:



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_expandedActiveRecord::Relation<LiveEvent>

A relation of LiveEvents that are next non webinars all expanded. Active Record Scope

Returns:

See Also:



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_webinarsActiveRecord::Relation<LiveEvent>

A relation of LiveEvents that are next webinars. Active Record Scope

Returns:

See Also:



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_allActiveRecord::Relation<LiveEvent>

A relation of LiveEvents that are next webinars all. Active Record Scope

Returns:

See Also:



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_deckObject



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_cacheObject

Alias for Class#clear_live_cache

Returns:

  • (Object)

    Class#clear_live_cache

See Also:



154
# File 'app/models/live_event.rb', line 154

delegate :clear_live_cache, to: :class

#duration_labelObject

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_minutesObject

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_cacheObject

Alias for Class#flush_edge_cache

Returns:

  • (Object)

    Class#flush_edge_cache

See Also:



152
# File 'app/models/live_event.rb', line 152

delegate :flush_edge_cache, to: :class

#to_event_schemaObject

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_sObject



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_liveObject

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