如何使用 memcached 刷新 Rails 4 中的类方法



我在Rails 4应用程序中有以下内容:

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

但缓存永远不会刷新。 此缓存显示最新添加的 5 个更新,但当我添加新更新时,它不会刷新缓存。

我已经验证了内存缓存正在运行。 这是在开发环境中,但我已为该环境打开缓存。

我在这里做错了什么?

问题是您在类方法和实例方法中使用self.class.name

首先,这是解决方案,self.cached_latest更改为:

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

在自点方法(类方法)中,您已经在class中,因此调用self.class将返回类的类,该类将是Class的,而不是您期望的Update(模型类的名称)

在实例方法flush_cacheself.class.name的调用正确返回Update 。因此,当您after_commit时,它试图刷新['Update', 'latest']缓存键,但您的self.cached_latest类方法正在写入['Class', 'latest']缓存键。

因此,问题在于您从两个不同的上下文调用self.class.name,并且它返回了不同的值。

为了改进您的解决方案,您可以使用自破坏缓存键来取消after_commit回调:

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

此缓存键现在如下所示:

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

正如您现在可能知道的那样,一旦您创建或更新记录,向其添加expires,您将拥有一个自我刷新缓存,此缓存键就会更改。

最新更新