Class: SpreeCmCommissioner::VotingSession
- Inherits:
-
Base
- Object
- Base
- SpreeCmCommissioner::VotingSession
- Includes:
- StoreMetadata, VotingSessionConfigConcern, VotingSessionLiveStreamConcern, VotingSessionTimingConcern
- Defined in:
- app/models/spree_cm_commissioner/voting_session.rb
Constant Summary
Constants included from VotingSessionConfigConcern
SpreeCmCommissioner::VotingSessionConfigConcern::DEFAULT_SUGGESTION_TOP_N
Constants included from VotingSessionTimingConcern
SpreeCmCommissioner::VotingSessionTimingConcern::LIVE_STATE_COLUMNS
Class Method Summary collapse
-
.current_or_next_upcoming ⇒ Object
Priority 1: Current session wins over Upcoming session.
Instance Method Summary collapse
- #active? ⇒ Boolean
- #can_vote? ⇒ Boolean
- #find_or_create_voting_contestant(show_contestant) ⇒ Object
-
#first_in_episode? ⇒ Boolean
True when this session is the first in its episode.
-
#missing_show_contestants ⇒ Object
Show contestants expected in this session but not yet assigned.
-
#next_in_episode ⇒ Object
Returns the next advanceable session within the same episode (by position).
- #past? ⇒ Boolean
-
#paused? ⇒ Boolean
Defined here rather than in VotingSessionTimingConcern: the
enum status:macro above generates its ownpaused?predicate (status == "paused", no time check) directly on this class, and a same-named method defined in an included module is always shadowed by one defined directly on the class — regardless of load order. - #upcoming? ⇒ Boolean
Methods included from VotingSessionConfigConcern
#effective_fraud_config, #effective_suggestion_top_n, #effective_voting_config, #max_votes_per_user, #rate_limit_max_votes, #rate_limit_window
Methods included from VotingSessionTimingConcern
#extend_vote!, #start_vote!, #stop_vote!, #vote_window_pending?
Methods included from VotingSessionLiveStreamConcern
Class Method Details
.current_or_next_upcoming ⇒ Object
Priority 1: Current session wins over Upcoming session. Priority 2: Follow manual position (Managed by acts_as_list).
99 100 101 102 103 104 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 99 def self.current_or_next_upcoming current.or(upcoming).order( Arel.sql('CASE WHEN opens_at <= CURRENT_TIMESTAMP AND closes_at >= CURRENT_TIMESTAMP THEN 0 ELSE 1 END'), :position ) end |
Instance Method Details
#active? ⇒ Boolean
75 76 77 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 75 def active? enabled? && Time.current.between?(opens_at, closes_at) end |
#can_vote? ⇒ Boolean
106 107 108 109 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 106 def can_vote? enabled? && vote_open_at.present? && vote_close_at.present? && Time.zone.now.between?(vote_open_at, vote_close_at) && !manual_advance? end |
#find_or_create_voting_contestant(show_contestant) ⇒ Object
111 112 113 114 115 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 111 def find_or_create_voting_contestant(show_contestant) voting_contestants.find_or_create_by!(show_contestant: show_contestant) do |vc| vc.show_id = show.id end end |
#first_in_episode? ⇒ Boolean
True when this session is the first in its episode. e.g. position=1 → true; position=2 → false
125 126 127 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 125 def first_in_episode? position == 1 end |
#missing_show_contestants ⇒ Object
Show contestants expected in this session but not yet assigned. episode.season.show_contestants → all contestants on the season this episode belongs to. show_contestants → already assigned to this voting session. e.g. season has [Alice(active), Bob(active), Carol(eliminated)]; session only has [Alice] → returns [Bob]
133 134 135 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 133 def missing_show_contestants episode.season.show_contestants.active.where.not(id: show_contestants.select(:id)).ordered end |
#next_in_episode ⇒ Object
Returns the next advanceable session within the same episode (by position). Excludes pre_vote sessions. e.g. current session position=1 → returns session at position=2; last session → nil
119 120 121 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 119 def next_in_episode episode.voting_sessions.where('position > ?', position).where(session_type: %i[vote manual_advance]).order(:position).first end |
#past? ⇒ Boolean
83 84 85 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 83 def past? closed? || (closes_at.present? && Time.current > closes_at) end |
#paused? ⇒ Boolean
Defined here rather than in VotingSessionTimingConcern: the enum status: macro above
generates its own paused? predicate (status == "paused", no time check) directly on this
class, and a same-named method defined in an included module is always shadowed by one
defined directly on the class — regardless of load order. Only a class-body definition can
win here.
92 93 94 95 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 92 def paused? status == 'paused' && vote_open_at.present? && vote_close_at.present? && Time.current.between?(vote_open_at, vote_close_at) end |
#upcoming? ⇒ Boolean
79 80 81 |
# File 'app/models/spree_cm_commissioner/voting_session.rb', line 79 def upcoming? on_air? && Time.current < opens_at end |