# Caches\_page :if not executing (but caches\_action :if) does

**URL:** <https://www.ruby-forum.com/t/caches-page-if-not-executing-but-caches-action-if-does/149375>\
**Category:** Rails\
**Created:** [September 24, 2008, 9:30am UTC](https://www.ruby-forum.com/t/caches-page-if-not-executing-but-caches-action-if-does/149375 "2008-09-24T09:30:55Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![scottrutherford](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d07c76/32.png) [@scottrutherford](https://www.ruby-forum.com/u/scottrutherford)\
**Post date:** [September 24, 2008, 9:30am UTC](https://www.ruby-forum.com/t/caches-page-if-not-executing-but-caches-action-if-does/149375/1 "2008-09-24T09:30:55Z")

</div>

Hi folks -

Seeing a weird problem and would love some help. It’s documented in  
[http://pastie.org/278310](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]

---

<div class="post-metadata">

**Author:** ![scottrutherford](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d07c76/32.png) [@scottrutherford](https://www.ruby-forum.com/u/scottrutherford)\
**Post date:** [September 24, 2008, 6:55pm UTC](https://www.ruby-forum.com/t/caches-page-if-not-executing-but-caches-action-if-does/149375/2 "2008-09-24T18:55:12Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![scottrutherford](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d07c76/32.png) [@scottrutherford](https://www.ruby-forum.com/u/scottrutherford)\
**Post date:** [September 24, 2008, 6:34pm UTC](https://www.ruby-forum.com/t/caches-page-if-not-executing-but-caches-action-if-does/149375/3 "2008-09-24T18:34:33Z")

</div>

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](http://www.railsenvy.com/2007/2/28/rails-caching-tutorial) for  
an excellent tutorial on caching.

---

<div class="post-metadata">

**Author:** ![scottrutherford](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d07c76/32.png) [@scottrutherford](https://www.ruby-forum.com/u/scottrutherford)\
**Post date:** [September 24, 2008, 10:58pm UTC](https://www.ruby-forum.com/t/caches-page-if-not-executing-but-caches-action-if-does/149375/4 "2008-09-24T22:58:23Z")

</div>

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)
