标签: russian-doll-caching

使用has_many关系为俄罗斯玩偶缓存构建Rails应用程序

在研究了DHH和其他关于基于密钥的缓存过期和俄罗斯娃娃缓存的博客文章之后,我仍然不确定如何处理一种关系类型.具体来说,是一种has_many关系.

我将分享我对示例应用程序的研究结果.这是一个故事讲述,所以坚持下去.假设我们有以下ActiveRecord模型.我们所关心的只是模型的正确改变cache_key,对吗?

class Article < ActiveRecord::Base
  attr_accessible :author_id, :body, :title
  has_many :comments
  belongs_to :author
end

class Comment < ActiveRecord::Base
  attr_accessible :article_id, :author_id, :body
  belongs_to :author
  belongs_to :article, touch: true
end

class Author < ActiveRecord::Base
 attr_accessible :name
  has_many :articles
  has_many :comments
end
Run Code Online (Sandbox Code Playgroud)

我们已经有一篇文章,只有一条评论.两者都是由不同的作者.目标是cache_key在以下情况下对文章进行更改:

  1. 文章的正文或标题发生变化
  2. 它的评论的身体发生了变化
  3. 文章的作者姓名发生了变化
  4. 文章评论的作者姓名发生了变化

因此,默认情况下,我们对案例1和案例2都有好处.

1.9.3-p194 :034 > article.cache_key
 => "articles/1-20130412185804"
1.9.3-p194 :035 > article.comments.first.update_attribute('body', 'First Post!')
1.9.3-p194 :038 > article.cache_key
 => "articles/1-20130412185913"
Run Code Online (Sandbox Code Playgroud)

但不是案例3.

1.9.3-p194 :040 > article.author.update_attribute('name', 'Adam A.')
1.9.3-p194 :041 …
Run Code Online (Sandbox Code Playgroud)

ruby caching ruby-on-rails fragment-caching russian-doll-caching

23
推荐指数
1
解决办法
2518
查看次数

Rails缓存分页集合

只是对缓存分页项目集合的最佳方法进行一些研究.目前使用jbuilder输出JSON并且一直在玩各种cache_key选项.

我见过的最好的例子是使用最新记录的updated_at加上集合中的项目数量.

def cache_key
      pluck("COUNT(*)", "MAX(updated_at)").flatten.map(&:to_i).join("-")
end
Run Code Online (Sandbox Code Playgroud)

这里定义:https://gist.github.com/aaronjensen/6062912

但是这不适用于分页项目,我的集合中总共有10个项目.

这有什么变通方法吗?

pagination caching ruby-on-rails russian-doll-caching

8
推荐指数
1
解决办法
2786
查看次数

Rails 4.0.0.0使用belongs_to模型进行俄罗斯玩偶缓存

我在我的模型中设置了一个缓存

def self.latest(shop_id)
    Inventory.where(:shop_id => shop_id).order(:updated_at).last
end
Run Code Online (Sandbox Code Playgroud)

在我看来

<% cache ['inventories', Inventory.latest(session[:shop_id])] do %>

   <% @inventories.each do |inventory| %>

      <% cache ['entry', inventory] do %>     

     <li><%= link_to inventory.item_name, inventory %></li>
Run Code Online (Sandbox Code Playgroud)

所以,在这里我可以有很多商店,每个商店都有库存商品库存.以上缓存是否适用于不同的商店?

我认为即使在不同的商店中显示视图也可能会破坏缓存.或者,任何添加库存项目的商店都会破坏缓存.

我可以像这样使用俄罗斯娃娃缓存,还是需要在我的模型中使用Inventory.all?

ruby-on-rails-3 russian-doll-caching

6
推荐指数
1
解决办法
409
查看次数

Rails俄罗斯娃娃缓存和N + 1

根据我对Rails中俄罗斯娃娃缓存的理解,当我们进行RDC(俄罗斯娃娃缓存)时,这对于急切的加载相关对象或对象列表是有害的,因为在RDC中我们只是从数据库加载顶级对象,并查找它缓存渲染的模板和服务.如果我们要急切加载相关的对象列表,如果缓存不是陈旧的话,这将是无用的.

我的理解是否正确?如果是,我们如何确保我们在第一次调用时急切加载所有相关对象,以免在第一次加载(缓存不热)时支付N + 1个查询的成本.

caching ruby-on-rails ruby-on-rails-3 russian-doll-caching cache-digests

6
推荐指数
1
解决办法
622
查看次数

如何根据URL中的参数来破坏我的缓存密钥?

我有一个Profile#Index视图,我在这里渲染部分如此:

<% cache @profiles do %>
  <div class="wrapper wrapper-content">
  <% @profiles.to_a.in_groups_of(3, false).each do |profiles| %>
      <div class="row">
         <%= render partial: "profile", collection: profiles, cached: true %>
      </div>
    <% end %>
  </div>
<% end %>
Run Code Online (Sandbox Code Playgroud)

但在我看来app/views/profiles/_profile.html.erb,我有以下几点:

  <% cache profile do %>
    <% elsif current_user.has_role?(:coach) && params[:rating].present? %>
    <div class="contact-box-footer">
      <div class="row text-center avg-ratings">
        <div class="col-lg-3">
          <span class="label label-success">Speed: <%= profile.ratings.find_by(user: current_user).speed %></span>
        </div>
        <div class="col-lg-3">
          <span class="label label-info tackling">Tackling: <%= profile.ratings.find_by(user: current_user).tackling %></span>
        </div>
      </div>
    </div>
    <% …
Run Code Online (Sandbox Code Playgroud)

caching ruby-on-rails russian-doll-caching ruby-on-rails-5

6
推荐指数
1
解决办法
531
查看次数

为什么这个缓存语句没有写出我期望的密钥?

我有_profile.html.erb部分内容:

<% cache [current_user.roles.first, profile, @selected_profile, params[:rating]] do %>
Run Code Online (Sandbox Code Playgroud)

然而,这是我在服务器日志中看到的:

Read fragment views/profiles/26-20161212033839290582/profiles/52-20161213010040474070/profiles/14-20161213015458288839/profiles/34-20161212035644491093/profiles/33-20161212035644237925/profiles/38-20161207092843851446/profiles/35-20161212040016291016/profiles/36-20161212040016565707/profiles/4-20161213021028862933/profiles/39-20161207092843925084/profiles/46-20161207092844067579/profiles/47-20161207223703646028/profiles/37-20161212040016656625/660bdc6ad0b20e4c5329112cf79946f7 (0.1ms)
Run Code Online (Sandbox Code Playgroud)

我什么roles也没看到.

发生的事情是,如果我以具有admin角色的用户身份登录,然后以具有其他角色的用户身份登录,我看到profiles显示的缓存就像我是管理员而不是具有正确视图的其他用户.

可能导致这种情况的原因以及如何解决?

编辑1

如果我将cache语句更改为:

<% cache [current_user, profile, @selected_profile, params[:rating]] do %>
Run Code Online (Sandbox Code Playgroud)

并刷新,这是日志的样子:

Write fragment views/users/2-20161218005548388099/profiles/37-20161212040016656625///bb163edd4a8c7af2db71a04243338e7b (0.1ms)
  Rendered collection of profiles/_profile.html.erb [1 times] (25.4ms)
Write fragment views/profiles/26-20161212033839290582/profiles/52-20161213010040474070/profiles/14-20161213015458288839/profiles/34-20161212035644491093/profiles/33-20161212035644237925/profiles/38-20161207092843851446/profiles/35-20161212040016291016/profiles/36-20161212040016565707/profiles/4-20161213021028862933/profiles/39-20161207092843925084/profiles/46-20161207092844067579/profiles/47-20161207223703646028/profiles/37-20161212040016656625/83ddeaa031bf68e602ce66af2d268317 (0.1ms)
Run Code Online (Sandbox Code Playgroud)

编辑2

当我binding.pry进入时_profile.html.erb,我得到以下内容:

[3] pry(#<#<Class:0x007f968480ec98>>)> current_user.roles.first
=> #<Role:0x007f969e4422a8 id: 1, name: "admin", resource_id: nil, resource_type: nil, created_at: Mon, 12 Sep 2016 00:38:47 UTC +00:00, …
Run Code Online (Sandbox Code Playgroud)

caching ruby-on-rails russian-doll-caching ruby-on-rails-5

5
推荐指数
1
解决办法
134
查看次数