I want to do some heavy caching (russian doll caching as DHH calls it), but I’m not sure how to do it, because I have so much content that depends on the user and the attributes he has.
How would you do RDC on a view like this?:
<% if signed_in? %>
<div class="timeline">
<%= link_to image_tag(current_user.avatar), designer_path(current_user), :class => "avatar topimg" %>
<%= content_tag(:span, "your profile", :class => "description") %>
<%= link_to "", new_design_path, :class => "upload icon-upload" %>
<%= content_tag(:span, "upload a new design", :class => "description") %>
<%= link_to "", designer_path(current_user)+"/favorites", :class => "upload icon-star" unless current_user.followees_by_type("design").blank? %>
<%= content_tag(:span, "designs you've favorited", :class => "description") unless current_user.followees_by_type("design").blank? %>
<%= content_tag(:span, current_user.current_invites, :class => "invites_count") unless current_user.current_invites <= 0 || current_user.full_member == false %>
<%= link_to "", "#", :class => "invite icon-plus "+("blue" unless current_user.current_invites == 0).to_s unless current_user.current_invites < 0 || current_user.full_member == false %>
<%= content_tag(:span, "invite a friend ("+current_user.current_invites.to_s+" invites left)", :class => "description") unless current_user.current_invites < 0 %>
<%= content_tag(:span, activity, :class => "activity_count") unless activity == 0 %>
<%= link_to "", designer_path(current_user)+"/statistics", :class => "upload icon-activity "+("blue" unless activity == 0).to_s unless activity == 0 %>
<%= content_tag(:span, ("your activity ("+pluralize(activity, 'new thing')+")"), :class => "description") unless activity == 0%>
</div>
<% else %>
<%= link_to raw('<i class="icon-twitter icon-font"></i><span>login with twitter</span>'), "/auth/twitter", :class => "btn btn-twitter grey-tweet" %>
<% end %>
You can wrap the whole thing in one big cache block as follows:
This will cache it using the key timeline/#{@user.cache_key}. The cache_key contains the record id and updated_at by default, so the cached fragment is automatically invalidated* once the user record is updated.
Please note that if you use relations in your fragment (such as the followers), you should touch the user object every time one of the relations is updated. This can be accomplished automatically by setting :touch => true on the relation, as such:
(*) Please note that the outdated cache key is not really invalidated, it will just no longer be used. You should set an expiry on all cache keys or do some regular housekeeping to avoid overflowing your cache.