When a variant is destroyed, update product cache

This commit is contained in:
Rohan Mitchell
2016-01-28 15:17:17 +11:00
parent a0a61b65cb
commit 6d39cc39c6
3 changed files with 48 additions and 11 deletions

View File

@@ -10,7 +10,7 @@ Spree::Variant.class_eval do
include OpenFoodNetwork::VariantAndLineItemNaming
has_many :exchange_variants, dependent: :destroy
has_many :exchange_variants
has_many :exchanges, through: :exchange_variants
has_many :variant_overrides
@@ -26,16 +26,7 @@ Spree::Variant.class_eval do
before_validation :update_weight_from_unit_value, if: -> v { v.product.present? }
after_save :update_units
after_save :refresh_products_cache
around_destroy :refresh_products_cache_from_destroy
def refresh_products_cache
OpenFoodNetwork::ProductsCache.variant_changed self
end
def refresh_products_cache_from_destroy
OpenFoodNetwork::ProductsCache.variant_destroyed(self) { yield }
end
around_destroy :destruction
scope :with_order_cycles_inner, joins(exchanges: :order_cycle)
@@ -99,4 +90,20 @@ Spree::Variant.class_eval do
def update_weight_from_unit_value
self.weight = weight_from_unit_value if self.product.variant_unit == 'weight' && unit_value.present?
end
def refresh_products_cache
OpenFoodNetwork::ProductsCache.variant_changed self
end
def destruction
OpenFoodNetwork::ProductsCache.variant_destroyed(self) do
# Remove this association here instead of using dependent: :destroy because
# dependent-destroy acts before this around_filter is called, so ProductsCache
# has no way of knowing which exchanges the variant was a member of.
exchange_variants.destroy_all
# Destroy the variant
yield
end
end
end

View File

@@ -10,6 +10,17 @@ module OpenFoodNetwork
end
def self.variant_destroyed(variant, &block)
exchanges = exchanges_featuring_variant(variant).to_a
block.call
exchanges.each do |exchange|
refresh_cache exchange.receiver, exchange.order_cycle
end
end
private
def self.exchanges_featuring_variant(variant)

View File

@@ -51,6 +51,25 @@ module OpenFoodNetwork
end
end
describe "when a variant is destroyed" do
let(:variant) { create(:variant) }
let(:distributor) { create(:distributor_enterprise) }
let!(:oc) { create(:open_order_cycle, distributors: [distributor], variants: [variant]) }
it "refreshes the cache based on exchanges the variant was in before destruction" do
expect(ProductsCache).to receive(:refresh_cache).with(distributor, oc)
variant.destroy
end
it "performs the cache refresh after the variant has been destroyed" do
expect(ProductsCache).to receive(:refresh_cache).with(distributor, oc) do
expect(Spree::Variant.where(id: variant.id)).to be_empty
end
variant.destroy
end
end
describe "refreshing the cache" do
let(:distributor) { double(:distributor, id: 123) }
let(:order_cycle) { double(:order_cycle, id: 456) }