Caching模块用来实现caches_action/caches_page/fragment,普通用法没发现什么问题,问题在于使用下面的例子时,它不能缓存到正确的位置:
class CacheController < ApplicationController
caches_action :cache_one
caches_page :cache_two
#
end class TestController < ApplicationController
def one
render :inline => <<-EOS
Test::one<br />
<%= render_component :controller => 'cache', :action => 'cache_one' %>
EOS
end
def two
render :inline => <<-EOS
Test::two<br />
<%= render_component :controller => 'cache', :action => 'cache_two' %>
EOS
end
#
end cache_one和cache_two的实现就省略了。
访问直接访问这2个action,能够在正确的目录下生成缓存文件。不过访问test/one和test/two就会出现缓存错误,2个缓存文件被生成到CACHE_ROOT/test下,试想如果在多个地方使用render_component,就会产生很多份一样内容的缓存。
request会被传递给controller,当访问/test/one时,这个request保留有这个url。调用render_component时,会生成一个新的controller,这个request也被传递,不过url却还是/test/one,所以就有这个问题。
修复:
module ActionController #:nodoc:
module Caching
module Actions
class ActionCacheFilter #:nodoc:
def before(controller)
return unless @actions.include?(controller.action_name.intern)
url = controller.url_for(:controller => controller.controller_name, :action => controller.action_name)
if cache = controller.read_fragment(url.split("://").last)
controller.rendered_action_cache = true
controller.send(:render_text, cache)
false
end
end
def after(controller)
return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache
url = controller.url_for(:controller => controller.controller_name, :action => controller.action_name)
controller.write_fragment(url.split("://").last, controller.response.body)
end
end
end
end
end
通过替换controller和action来解决,测试结果正确。
不过还有其它问题没修复,比如url中参数的问题,虽然调用render_component时我并没有传递参数,但它还是把参数给传递了。另外没有修复caches_page和fragment。
其实这个问题是由render_component带来的,所以最好的修复办法当然是修复这个方法,让它处理正确的controller/action/params,暂时还没找出修复方法。