diff --git a/app/models/spree/image_decorator.rb b/app/models/spree/image_decorator.rb index 7d86aae3a6..24056926b7 100644 --- a/app/models/spree/image_decorator.rb +++ b/app/models/spree/image_decorator.rb @@ -1,4 +1,7 @@ Spree::Image.class_eval do + after_save :refresh_products_cache + after_destroy :refresh_products_cache + # Spree stores attachent definitions in JSON. This converts the style name and format to # strings. However, when paperclip encounters these, it doesn't recognise the format. # Here we solve that problem by converting format and style name to symbols. @@ -20,4 +23,11 @@ Spree::Image.class_eval do end reformat_styles + + + private + + def refresh_products_cache + viewable.try :refresh_products_cache + end end diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index b62b2440b2..9efa89795e 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -92,18 +92,29 @@ Spree::Variant.class_eval do end def refresh_products_cache - OpenFoodNetwork::ProductsCache.variant_changed self + if is_master? + product.refresh_products_cache + else + OpenFoodNetwork::ProductsCache.variant_changed self + end 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. + if is_master? exchange_variants(:reload).destroy_all - - # Destroy the variant yield + product.refresh_products_cache + + else + 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(:reload).destroy_all + + # Destroy the variant + yield + end end end end diff --git a/spec/models/spree/image_spec.rb b/spec/models/spree/image_spec.rb index 56665fa641..c9a9c1243c 100644 --- a/spec/models/spree/image_spec.rb +++ b/spec/models/spree/image_spec.rb @@ -14,5 +14,23 @@ module Spree Image.format_styles(formatted).should == {:mini => ["48x48>", :png]} end end + + describe "callbacks" do + let!(:product) { create(:simple_product) } + + let!(:image_file) { File.open("#{Rails.root}/app/assets/images/logo-white.png") } + let!(:image) { Image.create(viewable_id: product.master.id, viewable_type: 'Spree::Variant', alt: "image", attachment: image_file) } + + it "refreshes the products cache when changed" do + expect(OpenFoodNetwork::ProductsCache).to receive(:product_changed).with(product) + image.alt = 'asdf' + image.save + end + + it "refreshes the products cache when destroyed" do + expect(OpenFoodNetwork::ProductsCache).to receive(:product_changed).with(product) + image.destroy + end + end end end diff --git a/spec/models/spree/variant_spec.rb b/spec/models/spree/variant_spec.rb index 73789e62c2..11104a02e2 100644 --- a/spec/models/spree/variant_spec.rb +++ b/spec/models/spree/variant_spec.rb @@ -126,6 +126,25 @@ module Spree expect(OpenFoodNetwork::ProductsCache).to receive(:variant_destroyed).with(variant) variant.destroy end + + context "when it is the master variant" do + let(:product) { create(:simple_product) } + let(:master) { product.master } + + it "refreshes the products cache for the entire product on save" do + expect(OpenFoodNetwork::ProductsCache).to receive(:product_changed).with(product) + expect(OpenFoodNetwork::ProductsCache).to receive(:variant_changed).never + master.sku = 'abc123' + master.save + end + + it "refreshes the products cache for the entire product on destroy" do + # Does this ever happen? + expect(OpenFoodNetwork::ProductsCache).to receive(:product_changed).with(product) + expect(OpenFoodNetwork::ProductsCache).to receive(:variant_destroyed).never + master.destroy + end + end end describe "indexing variants by id" do