【问题标题】:rails4 double nested models russian-doll-cachingrails4 双嵌套模型俄罗斯娃娃缓存
【发布时间】:2016-07-20 07:08:15
【问题描述】:

我的 rails4 应用程序中的帖子具有以下结构。用户可以对帖子发表评论,回复可以写在 cmets 上。我想在页面上使用带有自动过期键的 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 %>

【问题讨论】:

  • 这个 repo README 可以帮助github.com/rails/cache_digestslol
  • abookyun,我已经检查过了,但这是旧语法。我只是想确保我做的一切都很好。这是我第一次实现缓存,一堆文章已经过时了,就像这个 repo 一样。

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


【解决方案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 %>

这可以通过在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 上。

两者之间的区别在于,当我们在部分中缓存时,Rails 会向每个对象的缓存存储(例如 memcache)发出一次get 命令。因此,如果您有 50 个 postcmets,则将有 50 个单独的请求对 memcached 进行检索。

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

【讨论】:

  • Jacbo,cached: true 怎么能改善这一点?我的意思是一切似乎都被缓存了。
  • 我明白了,感谢 Jacob 的解释。关于您的回答,我又意识到了一件事。为什么不在&lt;%= render @posts %&gt; 周围放置缓存。 &lt;% cache(['index-posts', @posts.map(&amp;:id), @posts.map(&amp;:updated_at).max]) do %&gt; 之类的东西?
  • 您也可以这样做,但您需要考虑到您还需要缓存用户updated_at 的帖子。否则当用户更改用户名时缓存不会失效。
  • 是的,这就是我想做的。在这种情况下没有意义,因为嵌套的东西肯定会改变。但我还有其他非常有用的模型。您能否在代码中添加您将如何做?所以这里的重点是你在“父”模型的(帖子)页面上显示“子”模型(评论、回复)。我很难找出另一种方式。我会为此写一个新问题。
  • 完成!如果我获得最新的updated_at,则在缓存对象的完整列表时,我从不缓存特定的 ID。这是因为如果我收到具有新 ID 的新帖子,最新的 updated_at 将同时更改,然后缓存键无论如何都会更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多