在进行片段缓存时,我们是否应该缓存活动记录查询?

时间:2012-08-08 08:01:29

标签: ruby-on-rails ruby-on-rails-3 caching memcached

如果一个是片段缓存页面的一部分,其中包含从控制器中的模型加载的内容。这些查询是否也应该被缓存?

这是否意味着将有两种类型的缓存:片段和活动支持缓存两种不同类型的数据?

例如。在视图中我可以:

<% cache 'videos_and_photos', :expires_in => 24.hours do %>
  <div id="videos">
    <% @videos.each do |video| %>
      ...
    <% end %>
  </div>

  <div id="photos">
    <% @photos.each do |photo| %>
       ...
    <% end %>
  </div>
<% end %>

并在控制器中:

Rails.cache.fetch('videos', :expires_in => 24.hours) do
  @videos = Video.where(...)
end

Rails.cache.fetch('photos', :expires_in => 24.hours) do
  @photos = Photo.where(...)
end

我唯一的关注是,如果一个缓存首先到期,那么数据将显示不一致。有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:1)

通常,不应在视图中使用业务逻辑或查询,但在这种情况下,可以进行异常。只需为查询定义一种特殊方法,例如Video.your_method,并在视图中使用它。这似乎是最干净的方法:

<% cache 'videos_and_photos', :expires_in => 24.hours do %>   
  <div id="videos">
    <% Video.your_method.each do |video| %>
      ...
    <% end %>   
  </div>

否则,您将缓存两个不同位置的数据,这可能会导致不可预测的结果。

答案 1 :(得分:0)

我创建了一个gem,以避免在存在缓存时查询数据库。

https://github.com/rovermicrover/FlagpoleSitta

它将所有数据库调用存储在Procs中,然后仅在缓存不存在时才调用它们。然后,当对象更新时,它会使所有相关的缓存无效。我从下面的stackoverflow帖子中得到了这个想法。

Best way to combine fragment and object caching for memcached and Rails

虽然我的宝石可能会过度杀戮,而我仍然认为它处于测试阶段,但上述堆栈溢出后的所有策略应该有所帮助。