rails4双嵌套模型俄罗斯娃娃缓存

时间:2016-03-31 17:33:58

标签: ruby-on-rails caching fragment-caching russian-doll-caching

我的rails4应用程序中有以下结构用于帖子。用户可以对帖子发表评论,并可以在评论上写回复。我想在页面上使用带有自动过期键的俄语玩偶缓存,但我不知道在这种情况下我应该如何做到这一点。

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

型号:

#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

文章/ 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 %>

1 个答案:

答案 0 :(得分:1)

你需要做一些事情

为您的belongs_to关系

添加触控功能

Post的子孙必须触摸他们的父母,以便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_reply.html.erb

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

可以使用cached: true函数中的render partial来改进这一点。但是,由于我们希望在用户更改用户名时使缓存失效,因此变得有点棘手。

如果覆盖所有模型cache_key函数,则可以这样做。

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

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

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

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

两者之间的区别在于,当我们缓存在部分 Rails中时,每个对象向缓存库(例如memcache)发出一次get命令。因此,如果您有50个后期评论,则会有50个单独的memcached请求来检索所有。{/ p>

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