简体   繁体   中英

How do I flush a class method in Rails 4 using memcached?

I have the following in a Rails 4 app:

class Update < ActiveRecord::Base
  default_scope { order('created_at desc') }

  after_commit :flush_cache

  def flush_cache
    Rails.cache.delete([self.class.name, 'latest'])
  end

  def self.cached_latest
    Rails.cache.fetch([self.class.name, 'latest']) { Update.all.limit(5) }
  end
end

But the cached is never flushed. This cache shows the latest 5 updates added, but when I add a new one, it's not flushing the cache.

I've verified memcached is running. This is in the development environment, but I have turned on caching for that environment.

What am I doing wrong here?

The problem is that you're using self.class.name in a class method and an instance method.

First, here's the solution, change self.cached_latest to:

def self.cached_latest
  Rails.cache.fetch([name, 'latest']) { Update.all.limit(5) }
end

In a self dot method (a class method) you're already in the class so calling self.class will return the class' class which would be Class and not Update as you're expecting (the name of your model class)

In the instance method flush_cache the call to self.class.name was correctly returning Update . So when you were after_commit ing, it was trying to flush the ['Update', 'latest'] cache key but your self.cached_latest class method was writing to the ['Class', 'latest'] cache key.

So, the problem was that you were calling self.class.name from two different contexts and it was returning a different value.

To improve upon your solution you could do away with the after_commit callback by using a self busting cache key:

def self.cached_latest
  Rails.cache.fetch([name, 'latest', count, order(updated_at: :desc).first.updated_at]) { Update.all.limit(5) }
end

This cache key would now look something like:

['Update', 'latest', 45, "date of latest record's updated_at timestamp"]

As you might be able to tell by now, this cache key would change as soon as you create or update a record, add an expires to it and you'll have a self flushing cache.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM