rails4 双嵌套模型 russian-doll-caching

rails4 double nested models russian-doll-caching

我的 posts 在我的 rails4 应用程序中有以下结构。用户可以在 post 上发表评论,并且可以在评论上写回复。我想在页面上使用带有自动过期键的 russian-doll-caching,但我不知道在这种情况下我应该怎么做。

sby可以告诉我在这种情况下如何使用它吗?

型号:

#post.rb

belongs_to :user
has_many :post_comments, dependent: :destroy

#post_comments.rb

belongs_to :user
belongs_to :post
has_many :post_comment_replies, dependent: :destroy

#post_comment_replies.rb

belongs_to :user
belongs_to :post_comments

posts/index.html.erb

 <div class="post-index new-post-insert">
   <%= render @posts %>
 </div>

_post.html.erb

<%= post.body %>
<%= post.user.full_name %>
....
<%= render partial: 'posts/post_comments/post_comment', collection: post.post_comments.ordered.included, as: :post_comment, locals: {post: post} %>

_post_comment.html.erb

<%= post_comment.body %>
<%= post_comment.user.full_name %>
......
<%= render partial: 'posts/post_comment_replies/post_comment_reply', collection: post_comment.post_comment_replies.ordered.included, as: :post_comment_reply, locals: { post_comment: post_comment } %>

_post_comment_reply.html.erb

<%= post_comment_reply.user.full_name %>
<%= post_comment_reply.body %>

你需要做一些事情

为您的 belongs_to 关系添加触摸

Post 的 children 和 grandchildren 需要触及它们的 parents 以便 updated_at 列更新,从而使缓存键无效.

#post_comments.rb

belongs_to :user
belongs_to :post, touch: true
has_many :post_comment_replies, dependent: :destroy

#post_comment_replies.rb

belongs_to :user
belongs_to :post_comments, touch: true

cache 命令添加到您的视图中

posts/index.html.erb

在帖子的主列表中,我们要缓存最新的 updated_at 帖子和最新的 updated_at 各个用户。

 <div class="post-index new-post-insert">
    <% cache ["posts", @posts.maximum(:updated_at).to_i, @posts.map {|p| p.user.try(:updated_at).to_i}.max] %>
     <%= render @posts %>
    <% end %>
 </div>

_post.html.erb

<% cache ["postlist", post, post.user] %>
  <%= post.body %>
  <%= post.user.full_name %>
  ....
  <%= render partial: 'posts/post_comments/post_comment', collection: post.post_comments.ordered.included, as: :post_comment, locals: {post: post} %>
<% end %>

_post_comment.html.erb

<% cache ["postcommentlist", post_comment, post_comment.user] %>
  <%= post_comment.body %>
  <%= post_comment.user.full_name %>
  ......
  <%= render partial: 'posts/post_comment_replies/post_comment_reply', collection: post_comment.post_comment_replies.ordered.included, as: :post_comment_reply, locals: { post_comment: post_comment } %>
<% end %>

_post_comment_回复.html.erb

<% cache ["postcommentreplylist", post_comment_reply, post_comment_reply.user] %>
  <%= post_comment_reply.user.full_name %>
  <%= post_comment_reply.body %>
<% end %>

这可以通过在 render partial 函数中使用 cached: true 来改进。然而,由于我们希望在用户更改用户名时使缓存过期,这就变得有点棘手了。

如果覆盖所有模型 cache_key 函数,就可以做到这一点。

为什么要在render partial中使用cached: true

而不是在每个部分调用 cache(就像我们上面做的那样)我们可以做

<%= render partial: 'posts/post_comments/post_comment', collection: post.post_comments, cached: true %>

如果我们只需要在 post_comment 的 updated_at 上缓存。

两者的区别在于,当我们缓存在partial中时Rails向缓存存储(例如memcache)发出一次get命令每 object。因此,如果您有 50 个评论,将有 50 个单独的请求到 memcached 以检索所有内容。

但是如果我们改为在 render 调用中使用 cached: true Rails 将向 memcached 发出 multi_get 请求并检索所有一个请求需要 50 object 秒。从而改善页面加载时间。在我们的生产环境中进行的测试中。它减少了 ~50ms - ~200ms 的页面加载时间,具体取决于数据量。