J'ai une application rails 4 utilisant pundit gem pour l'autorisation. Si je fais la mise en cache de fragments de poupées russes comme le code ci-dessous, l'instruction conditionnelle utilisée pour l'autorisation sera également mise en cache, ce qui n'est pas bon puisque les boutons edit/delete ne devraient être disponibles que pour le post.user
.des rails omettant certaines parties de la mise en cache des fragments
Quelle est la meilleure façon de contourner ce problème? Devrais-je diviser le cache en plus petites parties ou existe-t-il un moyen d'exclure certaines parties de la mise en cache? Quelle est la convention des rails dans ce cas?
index.html.erb
<% cache ["posts-index", @posts.map(&:id), @posts.map(&:updated_at).max, @posts.map {|post| post.user.profile.updated_at}.max] do %>
<%= render @posts %>
<% end %>
_post.html.erb
<% cache ['post', post, post.user.profile ] do %>
<div class="row>
<div class="col-md-2">
<%= link_to user_path(post.user) do %>
<%= image_tag post.user.avatar.url(:base_thumb), class: 'post-avatar' %>
<% end %>
</div>
<div class="col-md-8">
<span class="post-user-name"><%= post.user.full_name %></span>
<span class="post-updated"><%= local_time_ago(post.updated_at) %></span>
<div class="post-body">
<%= post.body %>
</div>
<div class="col-md-2" style="text-align:right;">
<!--############### THIS IS THE PART THAT SHOULD NOT BE CACHED #############-->
<% if policy(post).edit? && policy(post).delete? %>
<li class="dropdown">
<ul class = "dropdown-menu dropdown-menu-right">
<li>
<%= link_to "Edit Post", edit_post_path(post), remote: true, type: "button", 'data-toggle' => "modal", 'data-target' => "#updatepost_#{post.id}" %>
</li>
<li>
<a href="#" data-toggle="modal" role="button" data-target="#deletepost_<%= post.id %>">Delete Post</a>
</li>
</ul>
</li>
<% end %>
<!--########################## UNTIL HERE ############################-->
</div>
</div>
<div class = "row comment-top-row" style="padding-bottom:10px;">
<div class="col-md-12 post-comment-form">
<%= render partial: 'posts/post_comments/post_comment_form', locals: { post: post } %>
</div>
</div>
<div class = "row">
<div class="col-md-12 post-comment-insert-<%= post.id%>">
<%= render partial: 'posts/post_comments/post_comment', collection: post.post_comments.ordered.included, as: :post_comment, locals: {post: post} %>
</div>
</div>
<% if policy(post).edit? %>
<div class="modal fade updatepost" id="updatepost_<%= post.id %>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<!-- FORM GETS RENDERED HERE VIA JS -->
</div>
<% end %>
<% if policy(post).delete? %>
<div class="modal fade" id="deletepost_<%= post.id %>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
......
</div>
<% end %>
<% end %>
abookyun, est cette deuxième façon assez bon? La mise en cache ne perdra-t-elle pas son but? Je veux dire que comme vous l'avez mentionné, le fragment sera réécrit pour chaque utilisateur. En plus de cela, ne va-t-il pas consommer trop de mémoire à long terme? –
Pls également lire mon commentaire prev. J'ai oublié de mentionner (peut-être vous avez vu) que j'ai 'post_comment' imbriqué dans le' post' et 'post_comment_reply' imbriqué dans' post_comment'. Ceux-ci ne devraient être éditables que par le 'current_user', donc ceux-ci ont aussi des parties visibles uniquement par' current_user'. Est-ce que je dois changer ceux comme ceci ou «toucher» prend soin de cela? –
@SzilardMagyar IMHO: Comme je l'ai dit, c'est un problème de stratégie, seulement s'il est possible de sauvegarder des requêtes lourdes comme des requêtes postées et des commentaires imbriqués, par exemple, si le template change fréquemment, . Vous pouvez lire cet article pour savoir comment la mise en cache affecte la vitesse de votre application https://signalvnoise.com/posts/3690-the-performance-impact-of-russian-doll-caching – abookyun