# Expire\_fragment silently does nothing unless you use cache\_sweeper?

**URL:** <https://www.ruby-forum.com/t/expire-fragment-silently-does-nothing-unless-you-use-cache-sweeper/137323>\
**Category:** Rails\
**Created:** [May 12, 2008, 1:13am UTC](https://www.ruby-forum.com/t/expire-fragment-silently-does-nothing-unless-you-use-cache-sweeper/137323 "2008-05-12T01:13:22Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![skwp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5fc32e/32.png) [@skwp](https://www.ruby-forum.com/u/skwp)\
**Post date:** [May 12, 2008, 1:13am UTC](https://www.ruby-forum.com/t/expire-fragment-silently-does-nothing-unless-you-use-cache-sweeper/137323/1 "2008-05-12T01:13:22Z")

</div>

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](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](http://skwpspace.com)

---

<div class="post-metadata">

**Author:** ![skwp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5fc32e/32.png) [@skwp](https://www.ruby-forum.com/u/skwp)\
**Post date:** [May 14, 2008, 5:31am UTC](https://www.ruby-forum.com/t/expire-fragment-silently-does-nothing-unless-you-use-cache-sweeper/137323/2 "2008-05-14T05:31:30Z")

</div>

On 5/11/08, skwp [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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](http://blog.leetsoft.com/2007/5/22/the-secret-to-memcached) Only  
useful for memcache probably.

–  
Rick O.  
[http://lighthouseapp.com](http://lighthouseapp.com)  
[http://weblog.techno-weenie.net](http://weblog.techno-weenie.net)  
[http://mephistoblog.com](http://mephistoblog.com)
