From ca588fddd94ef2c4ace615ef26cbcb5d8bffe3e0 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Thu, 16 May 2024 12:24:16 +0200 Subject: [PATCH] Touch taxons individually after product update The Solidus implementation did not trigger `touch` on taxons, but updated the `updated_at` timestamp in an `update_all`. Since we want to invalidate ingredient spree taxons cache as well we need to use `touch` here and use the `after_touch` callback of `Spree::Taxon`. --- .../models/spree/spree_product_decorator.rb | 15 +++++++ spec/models/spree/product_spec.rb | 44 ++++++++++++------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/app/decorators/models/spree/spree_product_decorator.rb b/app/decorators/models/spree/spree_product_decorator.rb index e899d02..6df1b3f 100644 --- a/app/decorators/models/spree/spree_product_decorator.rb +++ b/app/decorators/models/spree/spree_product_decorator.rb @@ -7,6 +7,21 @@ def self.prepended(base) base.has_many :alchemy_ingredients, class_name: "Alchemy::Ingredients::SpreeProduct", as: :related_object, dependent: :nullify end + private + + # Overwritten Solidus' default behavior + # + # The Solidus implementation did not trigger `touch` on taxons, but + # updated the `updated_at` timestamp in an `update_all`. + # + # Since we want to invalidate ingredient spree taxons cache as well + # we need to use `touch` here and use the `after_touch` callback of + # Spree::Taxon + # + def touch_taxons + taxons.each(&:touch) + end + ::Spree::Product.prepend self end end diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index 088633d..22bbb70 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -9,26 +9,40 @@ let(:page) { create(:alchemy_page) } let(:page_version) { create(:alchemy_page_version, page: page) } let(:element) { create(:alchemy_element, page_version: page_version) } - let!(:ingredient) { Alchemy::Ingredients::SpreeProduct.create!(element: element, role: "product", related_object: product) } let(:product) { create(:product) } - it "invalidates the cache on update" do - travel_to 5.minutes.from_now do - current_time = Time.current - expect { product.reload.update!(name: "New name") }.to change { ingredient.reload.updated_at }.to(current_time) - expect(element.reload.updated_at).to eq(current_time) - expect(page_version.reload.updated_at).to eq(current_time) - expect(page.reload.updated_at).to eq(current_time) + context "if assigned to ingredient spree taxon" do + let!(:ingredient) { Alchemy::Ingredients::SpreeProduct.create!(element: element, role: "product", related_object: product) } + + it "invalidates the cache on update" do + travel_to 5.minutes.from_now do + current_time = Time.current + expect { product.reload.update!(name: "New name") }.to change { ingredient.reload.updated_at }.to(current_time) + expect(element.reload.updated_at).to eq(current_time) + expect(page_version.reload.updated_at).to eq(current_time) + expect(page.reload.updated_at).to eq(current_time) + end + end + + it "invalidates the cache on touch" do + travel_to 5.minutes.from_now do + current_time = Time.current + expect { product.reload.touch }.to change { ingredient.reload.updated_at }.to(current_time) + expect(element.reload.updated_at).to eq(current_time) + expect(page_version.reload.updated_at).to eq(current_time) + expect(page.reload.updated_at).to eq(current_time) + end end end - it "invalidates the cache on touch" do - travel_to 5.minutes.from_now do - current_time = Time.current - expect { product.reload.touch }.to change { ingredient.reload.updated_at }.to(current_time) - expect(element.reload.updated_at).to eq(current_time) - expect(page_version.reload.updated_at).to eq(current_time) - expect(page.reload.updated_at).to eq(current_time) + context "if assigned to taxon that is assigned to ingredient spree taxon" do + let(:taxon) { create(:taxon) } + let(:product) { create(:product, taxons: [taxon]) } + + let!(:ingredient) { Alchemy::Ingredients::SpreeTaxon.create!(element: element, role: "taxon", related_object: taxon) } + + it "touches ingredient spree taxons elements" do + expect { product.reload.touch }.to change { element.reload.updated_at } end end end