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 мс в зависимости от объема данных.