From 42266397aab80e376c149c474d073a655315a3b3 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 8 Mar 2017 12:19:50 +1100 Subject: [PATCH] Improving performance of available variant lookup for standing orders Only search the DB for available variants once --- app/forms/standing_order_form.rb | 12 +++++++++++- app/models/standing_line_item.rb | 6 ------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/forms/standing_order_form.rb b/app/forms/standing_order_form.rb index 213bcd6ac0..88d2158864 100644 --- a/app/forms/standing_order_form.rb +++ b/app/forms/standing_order_form.rb @@ -217,14 +217,24 @@ class StandingOrderForm end def standing_line_items_available? + available_variant_ids = variant_ids_for_shop_and_schedule standing_line_items.each do |sli| - unless sli.available_from?(shop_id, schedule_id) + unless available_variant_ids.include? sli.variant_id name = "#{sli.variant.product.name} - #{sli.variant.full_name}" errors.add(:standing_line_items, :not_available, name: name) end end end + def variant_ids_for_shop_and_schedule + Spree::Variant.joins(exchanges: { order_cycle: :schedules}) + .where(id: standing_line_items.map(&:variant_id)) + .where(schedules: { id: schedule}, exchanges: { incoming: false, receiver_id: shop }) + .merge(OrderCycle.not_closed) + .select('DISTINCT spree_variants.id') + .pluck(:id) + end + def build_msg_from(k, msg) return msg[1..-1] if msg.starts_with?("^") errors.full_message(k,msg) diff --git a/app/models/standing_line_item.rb b/app/models/standing_line_item.rb index e1d260e7bf..4c3185e45c 100644 --- a/app/models/standing_line_item.rb +++ b/app/models/standing_line_item.rb @@ -6,12 +6,6 @@ class StandingLineItem < ActiveRecord::Base validates :variant, presence: true validates :quantity, { presence: true, numericality: { only_integer: true } } - def available_from?(shop, schedule) - Spree::Variant.joins(exchanges: { order_cycle: :schedules}) - .where(id: variant_id, schedules: { id: schedule}, exchanges: { incoming: false, receiver_id: shop }) - .any? - end - def total_estimate (price_estimate || 0) * (quantity || 0) end