1

我在 Rails 缓存指南http://guides.rubyonrails.org/caching_with_rails.html中没有看到这个问题的解释,所以我想知道在这个例子中我是否可以问一下缓存是如何工作的。在我的用户个人资料页面上,我缓存了用户说的语言并将有效期设置为 15 分钟。当我这样做时,我假设如果用户在这 15 分钟到期之前更新他的语言,那么更新的语言将不会显示,因为缓存没有过期。但是,当我在我的应用程序上测试它时,更新的语言会立即显示,所以我假设更新会破坏缓存。如果是这样,那我为什么不将到期日期设置为 1 小时或无穷大呢?

  @languages = Rails.cache.fetch("lang", :expires_in => 15.minutes) do
    Language.where({:user_id => @user.id})
  end

请注意,如果这很重要,我将使用带有 memcached 的 Rails 4。

更新,如果到期时间只是由于大小限制而清除缓存,我应该将到期时间设置为多长时间?

我的个人资料页面上有很多信息(大约 15 个类似于下面的查询),如果用户不断刷新页面,我希望缓存这些信息,因此我打算这样做

 @endorsements = Rails.cache.fetch("endorsements", :expires_in => 15.minutes) do
    Endorsement.where({:subject_id => @user.id})
  end

  @languages = Rails.cache.fetch("lang", :expires_in => 15.minutes) do
    Language.where({:user_id => @user.id})
  end
4

2 回答 2

2

这是您需要在 Rails4 中执行的操作,以使缓存按您的预期工作(在开发中):

  1. 将“dalli”添加到您的 Gemfile
  2. 添加config.cache_store = :mem_cache_store到您的 config/environments/development.rb
  3. 添加config.action_controller.perform_caching = true到您的 config/environments/development.rb

(我知道你已经完成了#3)

完成后,您将不会再在日志中看到“SELECT *”,并且当您更新模型时,它不会自动更新您的缓存。

更新:

就像@FrederickCheung 所说,您需要缓存对象,而不是关系(查询)。最好的方法是对它们调用“to_a”。

于 2013-06-10T21:53:51.463 回答
2

您实际上并没有缓存任何东西:您只是在缓存ActiveRecord::Relation对象(这几乎只是查询的 ruby​​ 描述),而不是查询结果本身。

每次代码运行时,此查询都会被拉入未执行状态,然后再次运行。为了实现您想要做的事情,您需要强制执行查询,例如

 @endorsements = Rails.cache.fetch("endorsements", :expires_in => 15.minutes) do
    Endorsement.where({:subject_id => @user.id}).all
 end

缓存过期可能很棘手 - 有时让缓存的项目自动过期而不是确保更改数据的每一种方式都清除缓存更容易。在某些情况下,您甚至可能不知道数据何时更改,例如,如果您正在缓存外部 api 调用的结果。

于 2013-06-10T22:22:51.603 回答