# Update counter cache for 2 models

**URL:** <https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341>\
**Category:** Rails\
**Created:** [September 29, 2009, 9:59am UTC](https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341 "2009-09-29T09:59:27Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [September 29, 2009, 9:59am UTC](https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341/1 "2009-09-29T09:59:27Z")

</div>

Let’s say I have the following models:

User, has\_many :messages, :topics  
Forum, has\_many :topics  
Topic, belongs\_to :user, has\_many :messages  
Message, belongs\_to :user, :topic

How to tell both User and Topic, that a new Message has been created?

I can do: @user.messages \<\< @message, but what to do to notify the  
@topic? Is it possible to do that in a pretty manner?

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [September 29, 2009, 10:43am UTC](https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341/2 "2009-09-29T10:43:13Z")

</div>

Crap, after doing some tests it appears, that Rails needs to refetch the  
user and topic objects from DB before updating their count columns.

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [September 29, 2009, 10:51am UTC](https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341/3 "2009-09-29T10:51:39Z")

</div>

Create an observer for the message model and do your updates.

On Sep 29, 12:59 pm, Fernando P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [September 29, 2009, 11:11am UTC](https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341/4 "2009-09-29T11:11:28Z")

</div>

Mukund wrote:

> Create an observer for the message model and do your updates.

It doesn’t work either. Inside the observer method, I won’t have access  
to @user and @topic.

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [September 29, 2009, 1:49pm UTC](https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341/5 "2009-09-29T13:49:36Z")

</div>

> Can you not just do @topic.messages \<\< @message

then the message is missing the user\_id.

A found a way:

message = user.messages.build(:content =\> ‘blabla’)  
topic.messages \<\< message.

But to update the counter columns, then rails does 2 redundant select  
queries: one for topic and one for user then updates the counter  
columns, although user and topic objects are already available.

I could code that manually but it doesn’t look pretty. I think some time  
ago Fred Cheung said that intelligent reserve associations would be  
available in Rails 3, for now rails has to do redundant selects in order  
to update the objects. Maybe there is another and better way to achieve  
what I want?

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [September 29, 2009, 1:02pm UTC](https://www.ruby-forum.com/t/update-counter-cache-for-2-models/176341/6 "2009-09-29T13:02:50Z")

</div>

2009/9/29 Fernando P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Let’s say I have the following models:
> 
> User, has\_many :messages, :topics  
> Forum, has\_many :topics  
> Topic, belongs\_to :user, has\_many :messages

Topic is missing a belongs\_to :Forum

> Message, belongs\_to :user, :topic
> 
> How to tell both User and Topic, that a new Message has been created?
> 
> I can do: @user.messages \<\< @message, but what to do to notify the  
> @topic? Is it possible to do that in a pretty manner?

Can you not just do @topic.messages \<\< @message

Are you sure you have your relationships right? For example does the  
topic that a message belongs to also belong to the same user? If so  
then for user you want has\_many through on one of them, through the  
other.

Colin
