I am using fragment caching in order to speed up the rendering time of Comfortable Mexican Sofa. However, I cannot figure out how to get it to expire the cache for a particular object when I update it.
I am using Comfy as a CMS for a company website that I am building. To allow for dynamic page content I have set it up so it renders directories of pages as blocks of content.
class WelcomeController < ApplicationController
def index
@testimonials = Comfy::Cms::Page.find_by_full_path!("/testimonials").children
@clients = Comfy::Cms::Page.find_by_full_path!("/clients").children
@recent_blogs = Comfy::Cms::Page.find_by_full_path!("/blog").children.published.last(4)
@team = Comfy::Cms::Page.find_by_full_path!("/team").children
end
end
I am then rendering the collections using the cms_block_content
helpers given by CMS.
<% @clients.each do | client |%>
<img class="client__logo lazy" data-original="<%=cms_block_content(:client_logo, client).file.url%>">
<%end%>
I also introduced some fragment caching as all the inline rendering was massively slowing down the loading of the page.
However, I have run into a problem. When I create or delete new content it appears/disappears on the page fine, however, when I update content the content on the page doesn't update. Updating content doesn't seem to expire the cached content (if you run Rails.cache.clear
then the updated content loads).
I looked into creating a cache sweeper as posited in the CMS documentation but I wasn't quite sure how to proceed as I am not sure what parameters to pass through to the actual expire_fragment
method.
class CmsAdminSweeper < ActionController::Caching::Sweeper
observe Comfy::Cms::Page
def after_update(record)
do_sweeping(record)
end
def do_sweeping(record)
# return unless modification is made from controller action
return false if session.blank? || assigns(:site).blank?
Rails.logger.info("CmsAdminSweeper.do_sweeping in progress...")
expire_fragment({ controller: '/welcome', action: 'index', id: record.id})
end
end
Is this the best way to proceed? If so, what can I pass through to the expire_fragment method?
Many thanks!
Tom
The correct answer had in fact been staring me in the face the entire time, I just didn't quite realise it. All I needed to do was pass in the record.
expire_fragment(record)
However, the reason that it wasn't working when I first tried it was due to the fact that a digest is added to the cache when it is saved. This means that you cannot expire them manually. Therefore, when you cache the view you need to make sure that you are skipping the digest.
<% @clients.each do | client |%>
<% cache client, skip_digest: true do %>
<img class="client__logo lazy" data-original="<%=cms_block_content(:client_logo, client).file.url%>">
<%end%>
<%end%>
Et voila! It works.