Reputation: 2411
I have been using cache for a long time and recently discovered that my fragment caching doesn't stop my controller from executing the code, as it always has been. I have boiled the problem down to have to do with the cache_key that seems to be a new feature?
This is my previous solution that no longer works as expected.
Product#Show-view:
cache('product-' + @product.id.to_s) do
# View stuff
end
Product#Show-controller:
unless fragment_exist?('product-19834') # ID obviously dynamically loaded
# Perform slow calculations
end
The caching works fine. It writes and reads the fragment, but it still executes the controller (which is the whole reason I want to use caching). This boils down to the fragment has an added unique id so the fragment created is something like:
views/product-19834/b05c4ed1bdb428f73b2c73203769b40f
So when I check if the fragment_exist I am not checking for the right string (since I am checking for 'views/product-19834'). I have also tried to use:
fragment_exist?("product-#{@product.id}/#{@product.cache_key}")
but it checks with a different cache_key than is actually created.
I would rather use this solution than controller-caching or gems like interlock.
My question is: - How do I, in the controller, check if a fragment exist for a specific view considering this cache key?
Upvotes: 3
Views: 1222
Reputation: 2144
It might be worth pointing out that while the proposed solution (fragment_exist?
) could work, it's more like a hack.
In your question, you say
It writes and reads the fragment, but it still executes the controller (which is the whole reason I want to use caching)
So what you actually want is "controller caching". But fragment caching is "view caching":
Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store (Rails Guides 5.2.3)
For "controller caching", Rails already provides some options:
Which are all, from my point of view, better suited for your particular use case.
Upvotes: 1
Reputation: 2411
As Kelseydh pointed out in the link, the solution to this is to use skip_digest => true in the cache request:
View
cache ("product" + @product.id, :skip_digest => true)
Controller
fragment_exist?("product-#{@product.id}")
Upvotes: 7