I need to expire fragment caches from a background job. The usual way to
expire caches is to create a cache sweeper and put the observer hooks
the controller. That is fine as long as database is only modified
But in this case I have a background job importing data, and that needs
invalidate fragment caches for records it touches. The most elegant way
would be to able to install the sweeping observer while the background
is running so it will expire all touched object’s caches.
Thinking further, sometimes from the Rails console, I’m starting manual
imports by invoking MyModel.import_all! on the model that’s going to
data. Now, how would caches be expired here? Clearly, the MVC way cannot
Time to break the rules. So, what would be the best approach to handle
I’m seeing three ways with different downsides but only one that would
Expire fragments through observers the MVC way
Downside: Background importers won’t purge caches because only
controllers install sweepers/observers.
Conclusion: This is no option.
Expire fragments through observers installed in controllers and
Downside: No sweeping when running imports from console.
Conclusion: Probably the cleanest solution but not a real option.
Expire fragments directly from the models
Downside: Not the proposed MVC way, no support in Rails framework.
Conclusion: The only solution that works in a DRY way for me.
Looking at these points, I question the whole design behind sweepers and
their MVC voodoo. Trying to force cache sweeping into controllers only
somehow a failed design. I don’t see why that is. In the end, it’s the
that makes up the views. Why should a controller sweep its caches? Is it
performance reasons? Clearly it cannot be the choice about clearing its
views because other controllers could show results from the same models.
I often end up purging the caches from all controllers within the
While that is DRY it shows the misconception about making sweepers
to controllers only.
Replies to list only preferred.