Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Tim Morgan http://timmorgan.org

« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS 

Automatic Expiration of Rails Action Caching

Would love to get some feedback on this...

No doubt, 5 minutes after posting this, someone will tell me of the built-in Rails way of doing this, but alas I could not find it.

Usage looks like this:

   1  
   2  class PeopleController < ApplicationController
   3    caches_action :show, :for => 1.hour, :cache_path => Proc.new { |c| "people/#{c.params[:id]}_for_#{Person.logged_in.id}" }
   4  end


The ":for => 1.hour" part is where the magic happens.

Basically, this bit of code adds a before_filter that checks the last modified time of the cache entry, and expires it if it is older than the specified time period.

   1  
   2  module ActionController
   3    module Caching
   4      module Fragments
   5        # expire a cache key only if the block returns true or
   6        # if the age of the fragment is more than the specified age argument.
   7        def expire_fragment_by_mtime(key, age=nil, &block)
   8          block = Proc.new { |m| m < age.ago } unless block_given?
   9          if (m = cache_store.mtime(fragment_cache_key(key))) and block.call(m)
  10            expire_fragment(key)
  11          end
  12        end
  13      end
  14      module Actions
  15        module ClassMethods
  16          # adds an option :for
  17          # caches_action :show, :for => 2.hours, :cache_path => ...
  18          # :cache_path is required, unfortunately
  19          def caches_action_with_for(*actions)
  20            original_actions = actions.clone
  21            options = actions.extract_options!
  22            if for_time = options.delete(:for)
  23              cache_path = options[:cache_path]
  24              before_filter do |controller|
  25                cache_path = cache_path.call(controller) if cache_path.respond_to?(:call)
  26                controller.expire_fragment_by_mtime(cache_path, for_time)
  27              end
  28            end
  29            caches_action_without_for(*original_actions)
  30          end
  31          alias_method_chain :caches_action, :for
  32        end
  33      end
  34    end
  35  end
  36  
  37  # Add a method to grab the last modified time of the cache key.
  38  # If you use a store other than the FileStore, you'll need to add
  39  # a method like this to your store.
  40  module ActiveSupport
  41    module Cache
  42      class FileStore
  43        def mtime(name)
  44          File.mtime(real_file_path(name)) rescue nil
  45        end
  46      end
  47    end
  48  end
« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS