Skip to content

Instantly share code, notes, and snippets.

@taf2
Created December 16, 2009 23:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taf2/258304 to your computer and use it in GitHub Desktop.
Save taf2/258304 to your computer and use it in GitHub Desktop.
ActionController::Base.class_eval do
class << self
# when content_for is called we need to know the rendering actions cache_path
def caches_action_with_content_for(*actions)
#puts("#{self.inspect}: caches_action: #{actions.inspect}")
options = actions.last
options = {} unless options.is_a?(Hash)
#puts("#{self.inspect}: cache_path: #{options[:cache_path].inspect}")
@action_caches ||= {}
actions[0..actions.size-2].each do|act|
# get cache options
@action_caches[act] = options#.merge(:store_options => options.reject{|k,v| [:if,:only,:unless,:layout,:cache_path].include?(k) })
end
#puts("#{self.inspect}: #{@action_caches.inspect}")
caches_action_without_content_for(*actions)
end
alias_method_chain :caches_action, :content_for
end
end
ActionView::Base.class_eval do
=begin
def content_for_with_caching(name, content = nil, &block)
#key = "" # get the cache key from the caches_action
# to get the cache key for this we need to look for the caches_action around_filter
logger.info( controller.class.filter_chain.select{|f| f.class == ActionController::Filters::AroundFilter }.inspect )
options = controller.class.instance_variable_get(:@action_caches)
cache_path = ActionController::Caching::Actions::ActionCachePath.new(controller, path_options_for(controller, options.slice(:cache_path)))
logger.info(cache_path.path)
# logger.info(controller.action_cache_path.path)
# logger.info(controller.action_cache_path.inspect)
key = cache_path.path
# add to the cache_path name
key = "#{key};#{name}"
logger.info("content_for key: #{key.inspect} -> #{options[:store_options].inspect}")
cache(key, options[:store_options]) do
content_for_without_caching(name,content,&block)
end
end
alias_method_chain :content_for, :caching
=end
# from lib/action_controller/caching/actions.rb
def path_options_for(controller, options)
((path_options = options[:cache_path]).respond_to?(:call) ? path_options.call(controller) : path_options) || {}
end
end
ActionView::Template.class_eval do
def render(view, local_assigns = {})
puts "calling our version of the render method #{view.controller} -> #{view.action_name}"
compile(local_assigns)
view.with_template self do
view.send(:_evaluate_assigns_and_ivars)
view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
view.send(method_name(local_assigns), local_assigns) do |*names|
# if we got an Array, check to cache it
if names.is_a?(Array) and
# is caches_action used on the current rendering controller?
view.controller.class.instance_variable_defined?(:@action_caches) and
# get the options defined
(options = view.controller.class.instance_variable_get(:@action_caches)) and
# is this action included in the options?
options.key?(view.action_name.to_sym) and !names.first.blank?
puts "caching names: #{names.inspect}"
cache_path = ActionController::Caching::Actions::ActionCachePath.new(view.controller, view.path_options_for(view.controller, options.slice(:cache_path)))
key = "#{cache_path.path};#{names.first}"
cache_options = options[view.action_name.to_sym]
puts "use cache: #{key} #{view.action_name.to_sym.inspect} -> #{cache_options.inspect}"
# check the cache
buffer = view.controller.read_fragment(key,cache_options)
end
if buffer.blank?
puts "cache blank: #{names.inspect}"
ivar = :@_proc_for_layout
if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar))
buffer = view.capture(*names, &proc)
elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
puts "render #{ivar.inspect}"
buffer = view.instance_variable_get(ivar)
if ivar != :@content_for_layout and !options.nil? and options.key?(view.action_name.to_sym)
# if the action_caches instance variable was defined on the controller class for the current rendering action apply caching to the content_for blocks
# cache all except content_for_layout
puts "save fragment"
cache_path = ActionController::Caching::Actions::ActionCachePath.new(view.controller, view.path_options_for(view.controller, options.slice(:cache_path)))
key = "#{cache_path.path};#{names.first}"
cache_options = options[view.action_name.to_sym]
view.controller.write_fragment(key,buffer,cache_options)
end
end
end
buffer
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment