2010
10.02

Recently I had a need to add action caching to a Rails app that contained a fair about of dynamic data, so required frequent expiration of cached fragments.

There seemed to be plenty of information on creating Cache Sweepers that observed / implemented ActiveRecord callbacks (after_save, after_destroy etc…) but I could not find any good examples of implementing callbacks in the CacheSweeper for controller methods / actions.

Here is a short example of how to implement callbacks / observe action methods in a CacheSweeper:

Example Controller:

class BusinessesController < ApplicationController
  layout 'main'
 
  caches_action :businesss_directory, :show,
                 :if => Proc.new { |controller| !controller.user_authenticated? }, :layout => false
  cache_sweeper :business_sweeper, :only => [:sort_images]
 
  def business_directory
    #... implement business directory action
  end
 
  def show
    #... implement show action
  end
 
  def sort_images
    #... implements resort action
  end
end

So in my example, I want to observe the standard Business model as well as expire certain cache fragments when the sort_images method is called.

Let’s write a CacheSweeper implementation that will handle *both* for us.

class BusinessSweeper < ActionController::Caching::Sweeper
  #this will allow us to implement active record callbacks
  observe Business
 
  #after active record create
  def after_create(business)
    expire_cache_for(business)
    expire_directory_cache(business)
  end
 
  #after active record update
  def after_update(business)
    expire_cache_for(business)
    expire_directory_cache(business)
  end
 
  #after active record destroy
  def after_destroy(business)
    expire_cache_for(business)
    expire_directory_cache(business)
  end
 
  #Here we are going to observe / filter the controller action
  def after_businesses_sort_images
    expire_cache_for(assigns(:business))
  end
 
  private
 
  def expire_cache_for(business)
    expire_action(business_url(business))
  end
 
  def expire_directory_cache(business)
    expire_action(business_directory_url(business))
  end
end

In order to filter / observe the action on the controller we just need to include the controller name before the action name. If we want to reference any instance variables assigned inside the action, such as @business, we can use the assigns() method to get a handle on them.

It’s that easy!

No Comment.

Add Your Comment