I have a rails 4 app using pundit gem for authorization. If I do russian-doll fragment caching like the code below, the conditional statement used for authorization will be
Russian Doll Caching is simple but handy way for caching, there's no complex options or convention to exclude part of fragment from it. Above that, It's more relative to cache strategies. Here are two strategies for this user specific situation:
index.html.erb
<% # pull out cache %>
<%= render @posts %>
_post.html.erb
<% cache post %>
<%= # first part %>
<% end %>
<% # without cache %>
<%= # user specific part %>
<% cache post %>
<%= # third part %>
<% end %>
current_user
as part of cache_key
, which means you will have as many fragment caches as approximately your users and the fragments will automatically invalidate whenever the post or the user has changed their fingerprint. This is more elegant and maintainable. Here is an example: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, current_user ] 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;">
<% 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 %>
</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 %>