# Expiring Cache from Models

**URL:** <https://www.ruby-forum.com/t/expiring-cache-from-models/127056>\
**Category:** Rails\
**Created:** [January 24, 2008, 5:07pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056 "2008-01-24T17:07:26Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 24, 2008, 5:07pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/1 "2008-01-24T17:07:26Z")

</div>

Hi,

Is it possible to expire cache items (page, action, or fragment) from  
within a model? I know that sweepers let you trigger cache expiration  
on model changes, but they have to be activated in the controller.

I want to cache some things that can be potentially modified from many  
different controllers. It seems like it would be too easy to forget to  
activate the sweeper from some controller and then end up with a stale  
cache.

Expiring things by using just a plain after\_save hook in the model seems  
like it would be much safer to me, but I haven’t found a way to get to  
the expire\_ calls from within a model.

Is this possible? Or am I overlooking a reason why things shouldn’t be  
done this way?

Thanks!

Curtis H.

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 24, 2008, 9:49pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/2 "2008-01-24T21:49:37Z")

</div>

I found a way to do what I’m wanting, but it does seem a little awkward.  
From within the after\_save hook on the model, I do this:

ActionController::Base.fragment\_cache\_store.delete(name, nil)

Is there anything wrong with this approach? I don’t see it documented  
anywhere, but it seems to work just fine.

Thanks!

Curtis H.

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 24, 2008, 9:57pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/3 "2008-01-24T21:57:28Z")

</div>

> ActionController::Base.fragment\_cache\_store.delete(name, nil)  
> Is there anything wrong with this approach?

Yes, many things. You’re breaking MVC priciples that will lead to ugly  
ugly results down the road.

USE SWEEPERS

if you think your going to forget them some were stick them all in  
application\_controller in a before filter on everything until you  
familiarize your self with the code base.

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 24, 2008, 10:05pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/4 "2008-01-24T22:05:26Z")

</div>

Keynan P. wrote:

> > ActionController::Base.fragment\_cache\_store.delete(name, nil)  
> > Is there anything wrong with this approach?
> 
> Yes, many things. You’re breaking MVC priciples that will lead to ugly  
> ugly results down the road.
> 
> USE SWEEPERS
> 
> if you think your going to forget them some were stick them all in  
> application\_controller in a before filter on everything until you  
> familiarize your self with the code base.

I understand that it is breaking MVC a bit, but I’m still having trouble  
seeing why it’s so bad. It’s probably just my inexperience in this  
particular area, but could you give me a little bit more concrete  
example of why putting it in the model leads to ugly results?

Thanks for the tip on using the sweeper on the application controller.  
I hadn’t thought of that. But I guess I don’t really see how it’s that  
different from putting it right in the model. I mean, it will run every  
time, just as if it were in the model (or a regular observer on the  
model).

It doesn’t seem in keeping with DRY to have to remember to put a call to  
the sweeper on every new controller that could possibly affect the model  
that causes my fragments to become stale.

Sorry for all these questions, but I really do want to understand the  
reasoning behind this approach.

Thanks!

Curtis H.

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 24, 2008, 10:19pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/5 "2008-01-24T22:19:57Z")

</div>

Its the controllers Job to handle business logic. The model should only  
be responsible for data going to and from the database.

No this doesn’t violate DRY principles. You’re not duplicating the code  
for clearing the cache and preferably not duplicating the code that  
initializes the sweeper. You’re only duplicating a before filter because  
you’re giving it different actions to act before.

I am curious however why your model is getting modified by so many  
controllers?

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 24, 2008, 10:21pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/6 "2008-01-24T22:21:21Z")

</div>

To be clear in production code won’t be reloaded so you can just do

# ======================== SomeSweeper.instance class ApplicationController end

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 24, 2008, 10:31pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/7 "2008-01-24T22:31:07Z")

</div>

Keynan P. wrote:

> Its the controllers Job to handle business logic. The model should only  
> be responsible for data going to and from the database.
> 
> No this doesn’t violate DRY principles. You’re not duplicating the code  
> for clearing the cache and preferably not duplicating the code that  
> initializes the sweeper. You’re only duplicating a before filter because  
> you’re giving it different actions to act before.
> 
> I am curious however why your model is getting modified by so many  
> controllers?

Well, right now it’s only being modified by two controllers. One for  
normal editing of items and one for a bulk import of items. But in the  
future, we want to add one for bulk editing existing items, or we might  
want to expand the functionality of another controller to modify the  
items as a side effect of another operation.

But if the point is that every time the model changes, I know that this  
particular cache needs to be expired, why not define that behavior at a  
higher level? Even putting it at the application controller level  
doesn’t cover the case of modifying something at the console or  
modifying objects during a migration.

Anyway, I think attaching the sweeper to the application controller will  
do the trick for me for now.

Thanks!

Curtis H.

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [April 8, 2008, 9:14pm UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/8 "2008-04-08T21:14:32Z")

</div>

tonypm wrote:

> On Jan 24, 9:19 pm, Keynan P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > Its the controllers Job to handle business logic. The model should only  
> > be responsible for data going to and from the database.
> 
> is that strictly correct?
> 
> Tonypm

I think the correct way is keeping the business logic in the model and  
using the controllers to interact with the views/users. Also it is  
strongly advised to move any ruby code from the views into helpers or  
controllers. It will help you DRY things up and help designers do their  
job as well.

---

<div class="post-metadata">

**Author:** ![cghawthorne](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/4491bb/32.png) [@cghawthorne](https://www.ruby-forum.com/u/cghawthorne)\
**Post date:** [January 27, 2008, 11:28am UTC](https://www.ruby-forum.com/t/expiring-cache-from-models/127056/9 "2008-01-27T11:28:03Z")

</div>

On Jan 24, 9:19 pm, Keynan P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Its the controllers Job to handle business logic. The model should only  
> be responsible for data going to and from the database.

is that strictly correct?

Tonypm
