Rails Caching: Dynamic Fragments

I am finally getting around to implementing caching on my Rails application that I’ve been working on adamantly for the past couple of months.  For the time being, I am using a memcached server with simple action and page caching.  I ran into a few problems with my first few attempts at fragment caching and decided it wasn’t really necessary for the time being.  I needed a simple method of including small sections of dynamic code in an otherwise static page.  I then wanted to use action caching on the resulting view.  I’ll outline a simple method I used to achieve this.

I’ve been very happy with the results.  Very server intense requests are responding instantly.  This is all great, but caching is usually only appropriate for pages with content that is static for a period of time.  The biggest problem I was having is that there are very small pieces of the pages I wished to cache that are dynamic.  For instance, I want to have a bar at the top that tells the user who is logged in and provides a set of buttons to do things to their profile, etc.  An example of this is shown below:

Small Dynamic Block Showing User Profile Links

Small Dynamic Block Showing User Profile Links

So what I needed was an easy way to specify that this small block would be dynamic while still allowing the rest of the view to take advantage of action caching.  I’m sure there is some plugin that does this and more.  If there is a very good plugin that does just this, I would love to know about it in the comments.  For now, though I am going to provide my simple solution to the problem.

My solution was to create a partial for the profile summary.  I already had the block as a partial to make my view code more DRY.  Instead of this:

<%=render :partial => 'profile_summary'%>

in my view, I replaced it with an AJAX call using Prototype (updated to use Richard Poirier’s suggestion in the comments):

    <div id="info_panel">
        <%= javascript_tag remote_function(:url => { :controller => 'profile', :action => 'summary' }) %>
    </div>

I then have a controller that can repond to this AJAX request for the profile.

def summary
  render :update do |page|
    page.replace_html 'info_panel', :partial => '/profile/summary'
  end
end

Now, every time the page loads, it will load the entire page using the cached version.  It will then make an additional POST request to get the dymanic content.  This would become more complicated if there were many dynamic sections that I needed to load.  I feel like if it was wrapped into a plugin that could automatically handle special dynamic fragments inside a block like this:

<%=dynamic_fragment do%>
   <%=render :partial => 'profile_summary'%>
<%end%>

it would make it very easy and intuitive to insert dynamic fragments into an otherwise static page.  I do not have the need to implement something like this yet, I am satisfied with my simple solution.  I would be very happy to find a solution where you can specify the dynamic sections of the view instead of only specifying the static portions.  Then the system would magically build the server-side AJAX responses without the user having to do anything.  This allows the use of action_caches which are supposed to be much faster than fragment caching.  While I’m super busy with my project, stopping to create plugins is not on the priority list, but by writing it all down here I might come back to the best ideas.

I hope anybody looking to insert a small section of dynamic code in an otherwise action cacheable page finds this information useful.

Chase

blog comments powered by Disqus
© Chasing • Powered by Wordpress • Using the Swiss Cool theme.