I have set up a cache in my model like
def self.latest(shop_id)
Inventory.where(:shop_id => shop_id).order(:updated_at).last
end
and in my view
<% cache ['inventories', Inventory.latest(session[:shop_id])] do %>
<% @inventories.each do |inventory| %>
<% cache ['entry', inventory] do %>
<li><%= link_to inventory.item_name, inventory %></li>
So, here I can have many shops, each with an inventory of stock items. Will the above cache work at all for different shops?
I think it's possible that even displaying the view in a different shop will break the cache. Or, any shop adding an inventory item will break the cache.
Can I use Russian Doll caching like this or do I need to use Inventory.all in my model?
Your idea is close, but you need to include the shop_id
, the count
, and the maximum updated_at
of each shop's inventory into your cache key. Your outer cache needs to get busted when a shop's item gets deleted too, and that isn't covered under a max id
or updated_at
alone.
You can expand your custom cache key helper method to make this work. This allows you to create unique top level caches that only get busted when a member of that set gets added, updated or deleted. In effect, this gives a unique outer cache for each shop_id
. Thus when one shop's inventory is changed, it doesn't affect another shop's cache.
Here is an example, based on ideas in the edge rails documentation:
module InventoriesHelper
def cache_key_for_inventories(shop_id)
count = Inventory.where(:shop_id => shop_id).count
max_updated_at = Inventory.where(:shop_id => shop_id).maximum(:updated_at).try(:utc).try(:to_s, :number)
"inventories/#{shop_id}-#{count}-#{max_updated_at}"
end
end
Then in your view:
<% cache(cache_key_for_inventories(session[:shop_id])) do %>
...
<% end %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With