mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
optimize queries
This commit is contained in:
parent
8a422412d6
commit
7d5d935a65
8 changed files with 101 additions and 43 deletions
|
|
@ -3,9 +3,14 @@
|
||||||
module Admin
|
module Admin
|
||||||
class BaseController < ApplicationController
|
class BaseController < ApplicationController
|
||||||
before_action :verify_user_admin
|
before_action :verify_user_admin
|
||||||
|
before_action :load_all_conferences
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def load_all_conferences
|
||||||
|
@conferences = Conference.all
|
||||||
|
end
|
||||||
|
|
||||||
def current_ability
|
def current_ability
|
||||||
@current_ability ||= AdminAbility.new(current_user)
|
@current_ability ||= AdminAbility.new(current_user)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ class ApplicationController < ActionController::Base
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
add_flash_types :error
|
add_flash_types :error
|
||||||
protect_from_forgery with: :exception, prepend: true
|
protect_from_forgery with: :exception, prepend: true
|
||||||
before_action :get_conferences
|
|
||||||
before_action :store_location
|
before_action :store_location
|
||||||
# Ensure every controller authorizes resource or skips authorization (skip_authorization_check)
|
# Ensure every controller authorizes resource or skips authorization (skip_authorization_check)
|
||||||
check_authorization unless: :devise_controller?
|
check_authorization unless: :devise_controller?
|
||||||
|
|
@ -37,10 +36,6 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_conferences
|
|
||||||
@conferences = Conference.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_ability
|
def current_ability
|
||||||
@current_ability ||= Ability.new(current_user)
|
@current_ability ||= Ability.new(current_user)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ class ConferencesController < ApplicationController
|
||||||
load_and_authorize_resource find_by: :short_title, except: :show
|
load_and_authorize_resource find_by: :short_title, except: :show
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc)
|
@current, @antiquated = Conference.reorder(start_date: :asc).all.partition do |conference|
|
||||||
@antiquated = @conferences - @current
|
conference.end_date >= Date.current
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
|
||||||
|
|
@ -6,39 +6,52 @@ class SchedulesController < ApplicationController
|
||||||
before_action :respond_to_options
|
before_action :respond_to_options
|
||||||
load_resource :conference, find_by: :short_title
|
load_resource :conference, find_by: :short_title
|
||||||
load_resource :program, through: :conference, singleton: true, except: :index
|
load_resource :program, through: :conference, singleton: true, except: :index
|
||||||
|
before_action :load_withdrawn_event_schedules, only: [:show, :events]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@rooms = @conference.venue.rooms if @conference.venue
|
@event_schedules = @program.selected_event_schedules(
|
||||||
schedules = @program.selected_event_schedules
|
includes: [{ event: %i[event_type speakers submitter] }]
|
||||||
unless schedules
|
)
|
||||||
|
|
||||||
|
unless @event_schedules
|
||||||
redirect_to events_conference_schedule_path(@conference.short_title)
|
redirect_to events_conference_schedule_path(@conference.short_title)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@events_xml = schedules.map(&:event).group_by{ |event| event.time.to_date } if schedules
|
respond_to do |format|
|
||||||
@dates = @conference.start_date..@conference.end_date
|
format.xml do
|
||||||
@step_minutes = @program.schedule_interval.minutes
|
@events_xml = @event_schedules.map(&:event).group_by{ |event| event.time.to_date } if @event_schedules
|
||||||
@conf_start = @conference.start_hour
|
end
|
||||||
@conf_period = @conference.end_hour - @conf_start
|
|
||||||
|
|
||||||
# the schedule takes you to today if it is a date of the schedule
|
format.html do
|
||||||
@current_day = @conference.current_conference_day
|
@rooms = @conference.venue.rooms if @conference.venue
|
||||||
@day = @current_day.present? ? @current_day : @dates.first
|
@dates = @conference.start_date..@conference.end_date
|
||||||
unless @current_day
|
@step_minutes = @program.schedule_interval.minutes
|
||||||
# the schedule takes you to the current time if it is beetween the start and the end time.
|
@conf_start = @conference.start_hour
|
||||||
@hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour)
|
@conf_period = @conference.end_hour - @conf_start
|
||||||
|
|
||||||
|
# the schedule takes you to today if it is a date of the schedule
|
||||||
|
@current_day = @conference.current_conference_day
|
||||||
|
@day = @current_day.present? ? @current_day : @dates.first
|
||||||
|
unless @current_day
|
||||||
|
# the schedule takes you to the current time if it is beetween the start and the end time.
|
||||||
|
@hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour)
|
||||||
|
end
|
||||||
|
# Ids of the @event_schedules of confrmed self_organized tracks along with the selected_schedule_id
|
||||||
|
@selected_schedules_ids = [@conference.program.selected_schedule_id]
|
||||||
|
@conference.program.tracks.self_organized.confirmed.each do |track|
|
||||||
|
@selected_schedules_ids << track.selected_schedule_id
|
||||||
|
end
|
||||||
|
@selected_schedules_ids.compact!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# Ids of the schedules of confrmed self_organized tracks along with the selected_schedule_id
|
|
||||||
@selected_schedules_ids = [@conference.program.selected_schedule_id]
|
|
||||||
@conference.program.tracks.self_organized.confirmed.each do |track|
|
|
||||||
@selected_schedules_ids << track.selected_schedule_id
|
|
||||||
end
|
|
||||||
@selected_schedules_ids.compact!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def events
|
def events
|
||||||
@dates = @conference.start_date..@conference.end_date
|
@dates = @conference.start_date..@conference.end_date
|
||||||
|
@events_schedules = @program.selected_event_schedules(
|
||||||
@events_schedules = @program.selected_event_schedules
|
includes: [:room, { event: %i[track event_type speakers submitter] }]
|
||||||
|
)
|
||||||
@events_schedules = [] unless @events_schedules
|
@events_schedules = [] unless @events_schedules
|
||||||
|
|
||||||
@unscheduled_events = @program.events.confirmed - @events_schedules.map(&:event)
|
@unscheduled_events = @program.events.confirmed - @events_schedules.map(&:event)
|
||||||
|
|
@ -54,4 +67,10 @@ class SchedulesController < ApplicationController
|
||||||
format.html { head :ok }
|
format.html { head :ok }
|
||||||
end if request.options?
|
end if request.options?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_withdrawn_event_schedules
|
||||||
|
# Avoid making repetitive EXISTS queries for these later.
|
||||||
|
# See usage in EventsHelper#canceled_replacement_event_label
|
||||||
|
@withdrawn_event_schedules = EventSchedule.withdrawn_or_canceled_event_schedules(@program.schedule_ids)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ module EventsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def replacement_event_notice(event_schedule)
|
def replacement_event_notice(event_schedule)
|
||||||
if event_schedule.present? && event_schedule.replacement?
|
if event_schedule.present? && event_schedule.replacement?(@withdrawn_event_schedules)
|
||||||
replaced_event = (event_schedule.intersecting_event_schedules.withdrawn.first || event_schedule.intersecting_event_schedules.canceled.first).event
|
replaced_event = event_schedule.replaced_event_schedule.try(:event)
|
||||||
content_tag :span do
|
content_tag :span do
|
||||||
concat content_tag :span, 'Please note that this talk replaces '
|
concat content_tag :span, 'Please note that this talk replaces '
|
||||||
concat link_to replaced_event.title, conference_program_proposal_path(@conference.short_title, replaced_event.id)
|
concat link_to replaced_event.title, conference_program_proposal_path(@conference.short_title, replaced_event.id)
|
||||||
|
|
@ -40,7 +40,7 @@ module EventsHelper
|
||||||
def canceled_replacement_event_label(event, event_schedule, *label_classes)
|
def canceled_replacement_event_label(event, event_schedule, *label_classes)
|
||||||
if event.state == 'canceled' || event.state == 'withdrawn'
|
if event.state == 'canceled' || event.state == 'withdrawn'
|
||||||
content_tag :span, 'CANCELED', class: (['label', 'label-danger'] + label_classes)
|
content_tag :span, 'CANCELED', class: (['label', 'label-danger'] + label_classes)
|
||||||
elsif event_schedule.present? && event_schedule.replacement?
|
elsif event_schedule.present? && event_schedule.replacement?(@withdrawn_event_schedules)
|
||||||
content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes)
|
content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,17 @@ class EventSchedule < ApplicationRecord
|
||||||
scope :canceled, -> { joins(:event).where('state = ?', 'canceled') }
|
scope :canceled, -> { joins(:event).where('state = ?', 'canceled') }
|
||||||
scope :withdrawn, -> { joins(:event).where('state = ?', 'withdrawn') }
|
scope :withdrawn, -> { joins(:event).where('state = ?', 'withdrawn') }
|
||||||
|
|
||||||
|
scope :with_event_states, ->(*states){ joins(:event).where('events.state IN (?)', states) }
|
||||||
|
|
||||||
delegate :guid, to: :room, prefix: true
|
delegate :guid, to: :room, prefix: true
|
||||||
|
|
||||||
|
def self.withdrawn_or_canceled_event_schedules(schedule_ids)
|
||||||
|
EventSchedule
|
||||||
|
.unscoped
|
||||||
|
.where(schedule_id: schedule_ids)
|
||||||
|
.with_event_states(:withdrawn, :canceled)
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns end of the event
|
# Returns end of the event
|
||||||
#
|
#
|
||||||
|
|
@ -36,15 +45,41 @@ class EventSchedule < ApplicationRecord
|
||||||
# Returns event schedules that are scheduled in the same room and start_time as event
|
# Returns event schedules that are scheduled in the same room and start_time as event
|
||||||
#
|
#
|
||||||
def intersecting_event_schedules
|
def intersecting_event_schedules
|
||||||
EventSchedule.unscoped.where(room: room, start_time: start_time, schedule: schedule).where.not(id: id)
|
EventSchedule
|
||||||
|
.unscoped
|
||||||
|
.where(room_id: room_id, start_time: start_time, schedule_id: schedule_id)
|
||||||
|
.where.not(id: id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def replacement?
|
# event_schedule_source is a cached enumerable object that helps
|
||||||
event.state == 'confirmed' && (!intersecting_event_schedules.canceled.empty? || !intersecting_event_schedules.withdrawn.empty?)
|
# avoid repetitive EXISTS queries when rendering the schedule carousel partial
|
||||||
|
def replacement?(event_schedule_source = nil)
|
||||||
|
return false unless event.state == 'confirmed'
|
||||||
|
return replaced_event_schedules.exists? unless event_schedule_source
|
||||||
|
event_schedule_source.any? { |event_schedule| intersects_with?(event_schedule) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# the event schedule that `self` replaced
|
||||||
|
def replaced_event_schedule
|
||||||
|
replaced_event_schedules.first
|
||||||
|
end
|
||||||
|
|
||||||
|
# NOTE: This and `intersecting_event_schedules` share the flaw that they do not
|
||||||
|
# detect overlapping schedules where the start times are different (i.e., where
|
||||||
|
# only a portion of the time intersects).
|
||||||
|
def intersects_with?(other)
|
||||||
|
other != self &&
|
||||||
|
other.room_id == room_id &&
|
||||||
|
other.start_time == start_time &&
|
||||||
|
other.schedule_id == schedule_id
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def replaced_event_schedules
|
||||||
|
intersecting_event_schedules.with_event_states(:withdrawn, :canceled)
|
||||||
|
end
|
||||||
|
|
||||||
def start_after_end_hour
|
def start_after_end_hour
|
||||||
return unless event && start_time && event.program && event.program.conference && event.program.conference.end_hour
|
return unless event && start_time && event.program && event.program.conference && event.program.conference.end_hour
|
||||||
errors.add(:start_time, "can't be after the conference end hour (#{event.program.conference.end_hour})") if start_time.hour >= event.program.conference.end_hour
|
errors.add(:start_time, "can't be after the conference end hour (#{event.program.conference.end_hour})") if start_time.hour >= event.program.conference.end_hour
|
||||||
|
|
|
||||||
|
|
@ -77,12 +77,14 @@ class Program < ApplicationRecord
|
||||||
validate :check_languages_format
|
validate :check_languages_format
|
||||||
|
|
||||||
# Returns all event_schedules for the selected schedule ordered by start_time
|
# Returns all event_schedules for the selected schedule ordered by start_time
|
||||||
def selected_event_schedules
|
def selected_event_schedules(includes: [:event])
|
||||||
event_schedules = selected_schedule.event_schedules.order(start_time: :asc) if selected_schedule
|
event_schedules = []
|
||||||
tracks.self_organized.confirmed.order(start_date: :asc).each do |track|
|
event_schedules = selected_schedule.event_schedules.includes(*includes).order(start_time: :asc) if selected_schedule
|
||||||
event_schedules += track.selected_schedule.event_schedules.order(start_time: :asc) if track.selected_schedule
|
tracks.self_organized.confirmed.includes(selected_schedule: { event_schedules: includes }).order(start_date: :asc).each do |track|
|
||||||
|
next unless track.selected_schedule
|
||||||
|
event_schedules += track.selected_schedule.event_schedules
|
||||||
end
|
end
|
||||||
event_schedules.sort_by(&:start_time) if event_schedules
|
event_schedules.sort_by(&:start_time)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
@ -171,7 +173,8 @@ class Program < ApplicationRecord
|
||||||
# * +False+ -> If there is not any event for the given date
|
# * +False+ -> If there is not any event for the given date
|
||||||
def any_event_for_this_date?(date)
|
def any_event_for_this_date?(date)
|
||||||
parsed_date = DateTime.parse("#{date} 00:00").utc
|
parsed_date = DateTime.parse("#{date} 00:00").utc
|
||||||
EventSchedule.where(schedule: selected_schedule).where(start_time: parsed_date..(parsed_date + 1.day)).any?
|
range = parsed_date..(parsed_date + 1.day)
|
||||||
|
selected_schedule.event_schedules.any? { |es| range.cover?(es.start_time) }
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@
|
||||||
%td.room{ style: "height: #{ td_height(@rooms) }px;" }
|
%td.room{ style: "height: #{ td_height(@rooms) }px;" }
|
||||||
.room.elipsis.break-words{ style: "-webkit-line-clamp: #{ room_lines(@rooms) }; height: #{ room_height(@rooms) }px;" }
|
.room.elipsis.break-words{ style: "-webkit-line-clamp: #{ room_lines(@rooms) }; height: #{ room_height(@rooms) }px;" }
|
||||||
= room.name
|
= room.name
|
||||||
- event_schedules = room.event_schedules.select{ |e| @selected_schedules_ids.include?(e.schedule_id) && (e.end_time > start_time) && (e.start_time <= (start_time + hrs_per_slide.hour)) }
|
- event_schedules = @event_schedules.select{ |e| e.room_id == room.id && @selected_schedules_ids.include?(e.schedule_id) && (e.end_time > start_time) && (e.start_time <= (start_time + hrs_per_slide.hour)) }
|
||||||
- (1..intervals).each do |i|
|
- (1..intervals).each do |i|
|
||||||
- if span > 1
|
- if span > 1
|
||||||
- span -= 1
|
- span -= 1
|
||||||
- else
|
- else
|
||||||
- event_schedule = event_schedules.find{ |e| e.start_time <= start_room_time and e.end_time > start_room_time }
|
- event_schedule = event_schedules.find{ |e| e.start_time <= start_room_time and e.end_time > start_room_time }
|
||||||
- if event_schedule && (event_schedule.event.state == 'canceled' || event_schedule.event.state == 'withdrawn') && !event_schedule.intersecting_event_schedules.confirmed.empty?
|
- if event_schedule && (event_schedule.event.state == 'canceled' || event_schedule.event.state == 'withdrawn') && event_schedule.intersecting_event_schedules.confirmed.exists?
|
||||||
- replacement_event = event_schedule.intersecting_event_schedules.confirmed.first
|
- replacement_event = event_schedule.intersecting_event_schedules.confirmed.first
|
||||||
- event_schedule = (replacement_event.start_time <= start_room_time && replacement_event.end_time > start_room_time) ? replacement_event : nil
|
- event_schedule = (replacement_event.start_time <= start_room_time && replacement_event.end_time > start_room_time) ? replacement_event : nil
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue