Skip to content

Instantly share code, notes, and snippets.

@seven1m
Created April 23, 2009 03:51
Show Gist options
  • Save seven1m/100290 to your computer and use it in GitHub Desktop.
Save seven1m/100290 to your computer and use it in GitHub Desktop.
# 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.
module ActionController
module Caching
module Fragments
# expire a cache key only if the block returns true or
# if the age of the fragment is more than the specified age argument.
def expire_fragment_by_mtime(key, age=nil, &block)
block = Proc.new { |m| m < age.ago } unless block_given?
if (m = cache_store.mtime(fragment_cache_key(key))) and block.call(m)
expire_fragment(key)
end
end
end
module Actions
module ClassMethods
# adds an option :for
# caches_action :show, :for => 2.hours, :cache_path => ...
# :cache_path is required, unfortunately
def caches_action_with_for(*actions)
original_actions = actions.clone
options = actions.extract_options!
if for_time = options.delete(:for)
cache_path = options[:cache_path]
before_filter do |controller|
cache_path = cache_path.call(controller) if cache_path.respond_to?(:call)
controller.expire_fragment_by_mtime(cache_path, for_time)
end
end
caches_action_without_for(*original_actions)
end
alias_method_chain :caches_action, :for
end
end
end
end
# Add a method to grab the last modified time of the cache key.
# If you use a store other than the FileStore, you'll need to add
# a method like this to your store.
module ActiveSupport
module Cache
class FileStore
def mtime(name)
File.mtime(real_file_path(name)) rescue nil
end
end
end
end
class PeopleController < ApplicationController
caches_action :show, :for => 1.hour, \
:cache_path => Proc.new { |c| "people/#{c.params[:id]}_for_#{Person.logged_in.id}" }
end
# The ":for => 1.hour" part is where the magic happens.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment