Ruby Forum Ruby on Rails > expire_fragment silently does nothing unless you use cache_sweeper?

Posted by skwp (Guest)
on 12.05.2008 01:13
(Received via mailing list)
I've run into a very strange problem and I can't find any docs or any
code in rails core that can explain it.

The behavior is I have a sweeper which is a pure model sweeper so I
tried to use the

config.active_record.observers = [:my_sweeper]

to make it work. However it looks like if I don't use the
cache_sweeper declaration in the controller, the sweeper gets invoked
but the call to expire_fragment simply does nothing. I found only one
very slight reference to this in a post online -
http://www.ruby-forum.com/topic/145163#643061. But this seems to be a
highly obscure problem. Any ideas?

I put a 'puts' call into the rails core expire_cache method and it
appears to never get there..so the logical explanation is that someone
has overridden expire_cache somewhere to make it silently do nothing
and I can't seem to find where.

The whole point here is that I want my sweepers to act completely
transparently. I don't want to declare them in every controller. They
should just observe models and act on them. But this behavior is
getting in the way.

thanks!
Yan Pritzker
skwpspace.com
Posted by Rick Olson (Guest)
on 14.05.2008 05:31
(Received via mailing list)
On 5/11/08, skwp <yan.pritzker@gmail.com> wrote:
>  cache_sweeper declaration in the controller, the sweeper gets invoked
>  The whole point here is that I want my sweepers to act completely
>  transparently. I don't want to declare them in every controller. They
>  should just observe models and act on them. But this behavior is
>  getting in the way.

CacheSweepers need a controller instance to know how to expire caches.
 That's why the controller filters used by the #cache_sweeper method
in controllers are needed.

I see four solutions:

* Use #cache_sweeper in every controller that model is modified

* Add this bit of code to make sure your cache sweepers don't bomb
when they fire outside of controller filters:

class MySweeper
  def after_save(record)
    return if controller.nil?
    expire_cache /blah/
  end
end

* Set some #controller to some mock controller object that knows
enough about routing and ActionController::Caching to expire the cache
properly.  Though this could cause some confusion if people are
expecting other controller methods to be available too.

* Use some unique value that changes every time the record is updated
as part of the cache key.
http://blog.leetsoft.com/2007/5/22/the-secret-to-memcached  Only
useful for memcache probably.

--
Rick Olson
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com