caches_page :if not executing (but caches_action :if) does

Hi folks -

Seeing a weird problem and would love some help. It's documented in http://pastie.org/278310 to be more readable.

In short, I have a

caches_page "action", :if => {stuff}

but the :if is never being called - the action is just caching every time. (If I put a debugger call in the :if block, it never stops.)

If I replace caches_page with caches_action, the if evaluates correctly.

There are before_filters in the controller, but they do not apply to this action. (There's one in the supercontroller but it seems similarly irrelevant - just trims www. from URLs.)

What am I missing? Did I uncover an :if bug (which I doubt) or am I misunderstanding?

Full example (also in pastie):

#In this case, the :if is ignored, and all pages cache

class PagesController < ApplicationController   caches_page :show, :if => Proc.new {|c| ["home", "something- else"].index(c.request.path_parameters["id"])}

  before_filter :admin_required, :only => [ :index, :new, :create, :delete, :edit, :update ]   before_filter :IP_restricted, :only => [ :index, :new, :create, :delete, :edit, :update ]

#In this case, the :if executes correctly

class PagesController < ApplicationController # just changing caches_page to caches_action works   caches_action :show, :if => Proc.new {|c| ["home", "something- else"].index(c.request.path_parameters["id"])}

  before_filter :admin_required, :only => [ :index, :new, :create, :delete, :edit, :update ]   before_filter :IP_restricted, :only => [ :index, :new, :create, :delete, :edit, :update ]

Page caching (after the first access to a page) will write out a straight HTML file in /public/model/action.html to be found on any subsequent requests to that URL.

Subsequent requests to that URL will hit the cached page only, without ever invoking Rails. The notion of caches_page 'action', :if =>{stuff} is a non-starter.

caches_action always invokes Rails and runs your filters et al, hence the working :if => {stuff}

Check out http://www.railsenvy.com/2007/2/28/rails-caching-tutorial for an excellent tutorial on caching.

I'm confused by this. I get why once the page is cached that Rails won't execute again, but before the first cache attempt when Rails does run, the :if should fail.

There's documentation on caches_page 'action', :if => {}, so I know I'm not making up that format. So I'm still confused.

Well... the caches_page in my action_controller/caching/pages.rb uses an after_filter

def caches_page(*actions)   return unless perform_caching   options = actions.extract_options!   after_filter({:only => actions}.merge(options)) { |c| c.cache_page } end

whereas the caches_action in my action_controller/caching/actions.rb uses an around_filter

def caches_action(*actions)   return unless cache_configured?   options = actions.extract_options!   around_filter(ActionCacheFilter.new(:cache_path => options.delete(:cache_path)), {:only => actions}.merge(options)) end

Perhaps the caches_page should be an around_filter as well??? (This is an absolute shot-in-the-dark on my part)