cache_sweeper

Hi,

Why is cache_sweeper not a documented method? I was pretty sure it
used to be, but I could be wrong. I can't seem to find any
information on it anymore in the online docs.

As a side note, looking at the code for cache_sweeper it appears to
only work with the :only option, not :except (ignores it)... what's
the reason for this?

Thanks,
Andrew

Ok, the only documentation that exists for cache_sweeper seems to be
at http://api.rubyonrails.com/classes/ActionController/Caching/Sweeping.html

In addition to my comment about why cache_sweeper only accepts :only,
I found that the sweeper doesn't even appear to pay attention to
anything I pass to :only.

If I do...
cache_sweeper :my_sweeper, :only => :test

and call the :update action for example and the observed class in
my_sweeper is modified, the sweeper is still run.... even though I
told it to only use the observer for the :test action with :only =>
:test

Does anybody else see something similar in their code?

If what I said above makes no sense, what I'm saying is if you use
:only, replace any or all actions you specify in there with anything
and the observer will still get called. :only => :somerandomjunk

I'm using rails 2.0.2 btw

I ran into this the other day and it took me a while to figure out
what was going on. This is the paragraph in the Rails book (page 460):

"If a request comes in that invokes one of the actions that the
sweeper is filtering, the sweeper is activated.

If any of the Active Record observer methods fires, the page and
action expiry methods will be called.

If the Active Record observer gets invoked, but the current action is
not selected as a cache sweeper, the expire class in the sweeper are
ignored. Otherwise, expiry takes place"

I had something similiar. I had a method called upload() in my
photo_controller that I renamed to create(), but forgot to change the
cache_sweeper:

cache_sweeper :photo_sweeper, :only => [:upload]

My sweeper looked like this:

class PhotoSweeper < ActionController::Caching::Sweeper
  observe Photo

  def after_create(record)
    return if record.thumbnail?
    expire_fragment(%r{photo\/latest})
  end
end

This obviously made some caches not expire correctly. However, the
sweeper was still called, because one tells it to observe photos.
However, none of the calls to read_fragment or expire_fragment will
work. You can call them--they just return nil and do nothing.

Unlike the before/after/around_filters, the options :only and :except
don't dictate whether the callbacks (after_create and others) in the
sweeper are called or not. The options dictate whether the cache
expiry functions work while in the sweeper or not.

It seems that the sweepers observe according to their Observable
behavior--they're essentially active record observers, so they will
fire any time the AR class they're observing has a callback. The
sweeper options :only, and :except don't filter out calls, but only
that the cache expiry functions work.

I too found this a bit unintuitive, given how the
before/after/around_filters work. Does anyone else think/feel the
same?

Wow, so that's what it's doing. This explains the other "issue" I was
experiencing and that is with one of my other sweeper callbacks being
called that I specified from an entirely different controller (due to
the Observer being active at all times).

As the current "documentation" is right now, I'd sure say the way this
method works is unintuitive. cache_sweeper actually does a number of
other things that I was only able to extract from looking at it's
code. It allows (before|after)_controllername_action type methods to
be used as well, but the only place I've seen this documented is the
CHANGELOG from ages ago. :slight_smile:

Thanks for the comment Will.