rails leaving out some parts from fragment caching

前端 未结 1 1830
失恋的感觉
失恋的感觉 2020-12-21 15:34

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

相关标签:
1条回答
  • 2020-12-21 16:12

    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:

    1. Rearrange individually and Cache fragments manually, which I don't recommend. Because it's more complex and doesn't leverage the advantages of Russian Doll Caching. Not so maintainable as well. Here is an example:

    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 %>
    
    1. Preferred way: Add 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 %>
    
    0 讨论(0)
提交回复
热议问题