diff --git a/app/mailers/producer_mailer.rb b/app/mailers/producer_mailer.rb index 9f46b26a85..648fa7c69d 100644 --- a/app/mailers/producer_mailer.rb +++ b/app/mailers/producer_mailer.rb @@ -7,20 +7,18 @@ class ProducerMailer < Spree::BaseMailer @producer = producer @order_cycle = order_cycle - with_unscoped_products_and_variants do - load_data + load_data - I18n.with_locale(owner_locale) do - return unless orders?(order_cycle, producer) + I18n.with_locale(owner_locale) do + return unless orders?(order_cycle, producer) - mail( - to: @producer.contact.email, - from: from_address, - subject: subject, - reply_to: @coordinator.contact.email, - cc: @coordinator.contact.email - ) - end + mail( + to: @producer.contact.email, + from: from_address, + subject: subject, + reply_to: @coordinator.contact.email, + cc: @coordinator.contact.email + ) end end @@ -76,22 +74,4 @@ class ProducerMailer < Spree::BaseMailer def tax_total_from_line_items(line_items) Spree::Money.new line_items.to_a.sum(&:included_tax) end - - # This hack makes ActiveRecord skip the default_scope (deleted_at IS NULL) - # when eager loading associations. Further details: - # https://github.com/rails/rails/issues/11036 - def with_unscoped_products_and_variants - variant_default_scopes = Spree::Variant.default_scopes - product_default_scopes = Spree::Product.default_scopes - - Spree::Variant.default_scopes = [] - Spree::Product.default_scopes = [] - - return_value = yield - - Spree::Variant.default_scopes = variant_default_scopes - Spree::Product.default_scopes = product_default_scopes - - return_value - end end diff --git a/app/models/spree/line_item.rb b/app/models/spree/line_item.rb index bf58e337ab..2813bcfaf3 100644 --- a/app/models/spree/line_item.rb +++ b/app/models/spree/line_item.rb @@ -9,7 +9,7 @@ module Spree include LineItemStockChanges belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items - belongs_to :variant, class_name: "Spree::Variant" + belongs_to :variant, -> { with_deleted }, class_name: "Spree::Variant" belongs_to :tax_category, class_name: "Spree::TaxCategory" has_one :product, through: :variant @@ -153,18 +153,6 @@ module Spree @preferred_shipment = shipment end - # Remove product default_scope `deleted_at: nil` - def product - variant.product - end - - # This ensures that LineItems always have access to soft-deleted variants. - # In some situations, unscoped super will be nil. In these cases, - # we fetch the variant using variant_id. See issue #4946 for more details. - def variant - Spree::Variant.unscoped { super } || Spree::Variant.unscoped.find(variant_id) - end - def cap_quantity_at_stock! scoper.scope(variant) return if variant.on_demand diff --git a/app/models/spree/variant.rb b/app/models/spree/variant.rb index ed94fba1e6..275863beeb 100644 --- a/app/models/spree/variant.rb +++ b/app/models/spree/variant.rb @@ -13,7 +13,8 @@ module Spree acts_as_paranoid - belongs_to :product, touch: true, class_name: 'Spree::Product' + belongs_to :product, -> { with_deleted }, touch: true, class_name: 'Spree::Product' + delegate_belongs_to :product, :name, :description, :permalink, :available_on, :tax_category_id, :shipping_category_id, :meta_description, :meta_keywords, :tax_category, :shipping_category @@ -188,13 +189,6 @@ module Spree price_in(currency).try(:amount) end - # Product may be created with deleted_at already set, - # which would make AR's default finder return nil. - # This is a stopgap for that little problem. - def product - Spree::Product.unscoped { super } - end - # can_supply? is implemented in VariantStock def in_stock?(quantity = 1) can_supply?(quantity) diff --git a/spec/models/spree/line_item_spec.rb b/spec/models/spree/line_item_spec.rb index e8db788b9f..a43d7fba97 100644 --- a/spec/models/spree/line_item_spec.rb +++ b/spec/models/spree/line_item_spec.rb @@ -190,8 +190,17 @@ module Spree end end - it "finds line items sorted by name and unit_value" do - expect(o.line_items.sorted_by_name_and_unit_value).to eq([li6, li5, li4, li3]) + describe "#sorted_by_name_and_unit_value" do + it "finds line items sorted by name and unit_value" do + expect(o.line_items.sorted_by_name_and_unit_value).to eq([li6, li5, li4, li3]) + end + + it "includes soft-deleted products/variants" do + li3.variant.product.destroy + + expect(o.line_items.reload.sorted_by_name_and_unit_value).to eq([li6, li5, li4, li3]) + expect(o.line_items.sorted_by_name_and_unit_value.to_sql).to_not match "deleted_at" + end end it "finds line items from a given order cycle" do