Rails 4 Fragment Cache Entire Page. How to Expire Cache In Model

870 views Asked by At

How do I expire the main-page fragment in a model?

In my HTML

<% cache 'main-page' do %>
  # html here
<% end %>

In my Post Model

after_create :clear_cache
after_update :clear_cache

def clear_cache
  ActionController::Base.new.expire_fragment('main-page')
end

This doesn't clear the cache. If I create or update a post, the cache doesn't clear. If I run ActionController::Base.new.expire_fragment('main-page') in rails console it returns 'nil'. If I run Rails.cache.clear instead of ActionController::Base.new.expire_fragment('main-page') in the post model, it works.

1

There are 1 answers

2
Andrew Kuklewicz On BEST ANSWER

I believe your issue is the digest, so if you change your cache to this it should work:

<% cache 'main-page', skip_digest: true do %>
  # html here
<% end %>

If you want to use this kind of style, where the cache doesn't expire and relies on detecting model changes to invalidate, you may want to consider using an Observer or Sweeper, which were removed from Rails 4, but are useful for this pattern:

https://github.com/rails/rails-observers

Not the answer you are looking for perhaps, but another way:

Make the cache key based on the max updated_at from the Post model.

Whenever any post changes, the cache key will automatically miss and go retrieve the latest posts to re-cache that part of the view.

module HomeHelper
  def cache_key_for_posts
    count          = Post.count
    max_updated_at = Post.maximum(:updated_at).try(:utc).try(:to_s, :number)
    "posts/all-#{count}-#{max_updated_at}"
  end
end

And then in your view:

<% cache cache_key_for_posts, skip_digest: true do %>
  # html here
<% end %>