# STI, HABTM & counter\_cache

**URL:** <https://www.ruby-forum.com/t/sti-habtm-counter-cache/61296>\
**Category:** Rails\
**Created:** [May 22, 2006, 10:11pm UTC](https://www.ruby-forum.com/t/sti-habtm-counter-cache/61296 "2006-05-22T22:11:48Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![subimage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@subimage](https://www.ruby-forum.com/u/subimage)\
**Post date:** [May 22, 2006, 10:11pm UTC](https://www.ruby-forum.com/t/sti-habtm-counter-cache/61296/1 "2006-05-22T22:11:48Z")

</div>

Hello world…

I have an interesting issue that the online docs aren’t helping me with.

In my app I have 4 models

Item \< ActiveRecord  
Deal \< Item  
Product \< Item  
Category \< ActiveRecord

Item has\_and\_belongs\_to\_many :categories…

On each category record I’d like to maintain a product\_count and  
deal\_count  
to increase performance. This doesn’t appear possible with the current  
“counter\_cache” declaration.

Anyone have ideas on how to approach this?

In the past I’ve just run an hourly cron task to calculate & update all  
records of this type, but I feel this probably isn’t the most efficient  
(or  
accurate).

Ideas, comments?

---

<div class="post-metadata">

**Author:** ![subimage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@subimage](https://www.ruby-forum.com/u/subimage)\
**Post date:** [May 23, 2006, 12:31am UTC](https://www.ruby-forum.com/t/sti-habtm-counter-cache/61296/2 "2006-05-23T00:31:28Z")

</div>

On 5/22/06, subimage interactive [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On each category record I’d like to maintain a product\_count and deal\_count  
> to increase performance. This doesn’t appear possible with the current  
> “counter\_cache” declaration.
> 
> Anyone have ideas on how to approach this?

I don’t know how heavy the updating or saving of the model data is,  
but you can always use callbacks to do the counts before saving…

class Category \< ActiveRecord::Base  
def before\_save  
self.products\_count = Product.count(‘id’, :conditions =\>  
[“category\_id=?”,self.id])  
self.deals\_count = Deal.count(‘id’, :conditions =\>  
[“category\_id=?”,self.id])  
end  
end

–  
Sincerely,

Frodo L.

---

<div class="post-metadata">

**Author:** ![subimage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@subimage](https://www.ruby-forum.com/u/subimage)\
**Post date:** [May 23, 2006, 1:23am UTC](https://www.ruby-forum.com/t/sti-habtm-counter-cache/61296/3 "2006-05-23T01:23:22Z")

</div>

That’s not even where the updating will happen. This would work in a  
lazy  
fashion, but I was just looking to see if I overlooked anything in AR  
that  
would do it for me.

Currently I have a cron script that runs (just to make sure the numbers  
are  
right), plus my own add/remove category methods on Item that update the  
counts manually.

---

<div class="post-metadata">

**Author:** ![subimage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@subimage](https://www.ruby-forum.com/u/subimage)\
**Post date:** [May 23, 2006, 9:20am UTC](https://www.ruby-forum.com/t/sti-habtm-counter-cache/61296/4 "2006-05-23T09:20:01Z")

</div>

Figured out a nice way to handle this for those of you who search it out  
later.

There are 2 methods you can call on HABTM relationships “after\_add” and  
“after\_remove”. I’m calling update\_counts from there.
