Skip to content

Commit

Permalink
Touch taxons individually after product update
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
tvdeyen committed May 16, 2024
1 parent 378f7ca commit ca588fd
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 15 deletions.
15 changes: 15 additions & 0 deletions app/decorators/models/spree/spree_product_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
44 changes: 29 additions & 15 deletions spec/models/spree/product_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ca588fd

Please sign in to comment.