rails4 модели с двойным вложением

У меня есть следующая структура в моем приложении rails4 для постов. Пользователи могут комментировать пост и ответы могут быть написаны в комментариях. Я хотел бы использовать кеширование русской куклы с автоматически истекающими ключами на странице, но я не знаю, как именно это сделать в этом случае.

Может 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

сообщений / 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 ответ

Решение

Вам нужно сделать несколько вещей

Добавить прикосновение к вашему 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 командовать вашими взглядами

сообщений /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´s updated_at,

Разница между ними заключается в том, что когда мы кешируем внутри частичных Rails, get Команда к хранилищу (например, memcache) один раз за объект. Поэтому, если у вас 50 посткомментов, в memcached будет 50 отдельных запросов на получение всех.

Но если мы вместо этого будем использовать cached: true в render Call Rails выдаст multi_get запрос к memcached и извлечение всех 50 объектов за один запрос. Таким образом улучшается время загрузки страницы. В тестах мы провели в нашей производственной среде. Это уменьшило время загрузки страницы на ~50 мс - ~200 мс в зависимости от объема данных.

Другие вопросы по тегам