From 5518cf446f299a7a2ba567e4ed1cf8eb90a97763 Mon Sep 17 00:00:00 2001 From: Joaquin <20804419+joaquinco@users.noreply.github.com> Date: Thu, 6 Mar 2025 12:11:35 -0300 Subject: [PATCH] Eager load alerts and offline reservations on facility show (#5075) --- app/helpers/application_helper.rb | 2 +- .../concerns/products/scheduling_support.rb | 6 ++++- app/models/instrument.rb | 10 ++++----- app/models/product.rb | 22 +++++++++++-------- app/models/product_display_group.rb | 5 ++++- .../_product_display_group.html.haml | 2 +- 6 files changed, 28 insertions(+), 19 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index da1eb3eabc..0e1b4c16c6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -50,7 +50,7 @@ def facility_product_path(facility, product) def warning_if_instrument_is_offline_or_partially_available(instrument) if instrument.offline? tooltip_icon "fa fa-exclamation-triangle icon-large", t("instruments.offline.note") - elsif instrument.alert + elsif instrument.alert.present? tooltip_icon "fa fa-exclamation-triangle partially-available-warning icon-large", instrument.alert.note end end diff --git a/app/models/concerns/products/scheduling_support.rb b/app/models/concerns/products/scheduling_support.rb index b0029c225c..ac1a33287a 100644 --- a/app/models/concerns/products/scheduling_support.rb +++ b/app/models/concerns/products/scheduling_support.rb @@ -77,7 +77,11 @@ def quick_reservation_intervals end def offline? - current_offline_reservations.present? + if current_offline_reservations.loaded? + current_offline_reservations.present? + else + current_offline_reservations.exists? + end end def offline_category diff --git a/app/models/instrument.rb b/app/models/instrument.rb index c19c2fc2c0..06f0c6baf0 100644 --- a/app/models/instrument.rb +++ b/app/models/instrument.rb @@ -24,13 +24,11 @@ module Pricing end end.freeze - with_options foreign_key: "product_id" do |instrument| - instrument.has_many :admin_reservations - instrument.has_many :instrument_price_policies - instrument.has_many :offline_reservations - instrument.has_many :current_offline_reservations, -> { current }, class_name: "OfflineReservation" + with_options foreign_key: "product_id" do + has_many :admin_reservations + has_many :instrument_price_policies + has_many :offline_reservations end - has_one :alert, dependent: :destroy, class_name: "InstrumentAlert" email_list_attribute :cancellation_email_recipients email_list_attribute :issue_report_recipients diff --git a/app/models/product.rb b/app/models/product.rb index 8db6f5e267..6511528de8 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -23,10 +23,20 @@ class Product < ApplicationRecord has_one :product_display_group_product has_one :product_display_group, through: :product_display_group_product + # Instrument specifc + has_one( + :alert, + dependent: :destroy, + class_name: "InstrumentAlert", + foreign_key: :instrument_id, + inverse_of: :instrument + ) + has_many :current_offline_reservations, -> { current }, class_name: "OfflineReservation" + + before_save :start_time_disabled_daily_booking_only after_create :create_default_price_group_products after_create :create_skip_review_price_policies, if: :skip_review_mode? after_create :create_nonbillable_price_policy, if: :nonbillable_mode? - before_save :start_time_disabled_daily_booking_only email_list_attribute :training_request_contacts @@ -70,11 +80,9 @@ def self.billing_modes scope :mergeable_into_order, -> { not_archived.where(type: mergeable_types) } scope :cross_core_available, -> { where(cross_core_ordering_available: true) } scope :in_active_facility, -> { joins(:facility).where(facilities: { is_active: true }) } - scope :of_type, ->(type) { where(type: type) } + scope :of_type, ->(type) { where(type:) } scope :with_schedule, -> { where.not(schedule_id: nil) } - scope :without_display_group, -> { - left_outer_joins(:product_display_group_product).where(product_display_group_products: { id: nil }) - } + scope :without_display_group, -> { where.missing(:product_display_group_product) } # All product types. This cannot be a cattr_accessor because the block is evaluated # at definition time (not lazily as I expected) and this causes a circular dependency @@ -332,10 +340,6 @@ def is_accessible_to_user?(user) !(is_archived? || (is_hidden? && !is_operator)) end - def alert - nil - end - def duration_pricing_mode? false end diff --git a/app/models/product_display_group.rb b/app/models/product_display_group.rb index d346fe725b..f7bfb3c4e0 100644 --- a/app/models/product_display_group.rb +++ b/app/models/product_display_group.rb @@ -22,7 +22,10 @@ def to_s def self.fake_groups_by_type(products) Product.orderable_types.map do |type| - Fake.new(name: type.constantize.model_name.human(count: :many), products: products.where(type: type)) + Fake.new( + name: type.constantize.model_name.human(count: :many), + products: products.where(type:) + ) end end diff --git a/app/views/facilities/_product_display_group.html.haml b/app/views/facilities/_product_display_group.html.haml index e127e651c4..b28de3c6b8 100644 --- a/app/views/facilities/_product_display_group.html.haml +++ b/app/views/facilities/_product_display_group.html.haml @@ -1,4 +1,4 @@ -- collection = product_display_group.products.merge(@product_scope) +- collection = product_display_group.products.merge(@product_scope).includes(:alert, :current_offline_reservations) - if collection.present? .product_list{ class: classes } %h3= product_display_group