# Avoiding repeated calls to the DB

**URL:** <https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413>\
**Category:** Rails\
**Created:** [January 25, 2007, 8:47pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413 "2007-01-25T20:47:27Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 25, 2007, 8:47pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/1 "2007-01-25T20:47:27Z")

</div>

Let’s say I’ve got a forum app where there are Topic objects and Post  
objects.

Each Post has a topic\_id column and a parent\_id column.

Each topic has a root\_post that, minus error-checking, etc., boils down  
to:

def root\_post  
Post.find(  
:first,  
:conditions =\> “topic\_id = #{self.id} and parent\_id IS NULL”  
)  
end

Where can I store the root\_post so that I don’t have to go to the DB  
every time I need it?

This just _has_ to be brain dead simple, but I haven’t found the answer  
yet.

If I put any ActiveRecord into the session, I get marshalling problems  
when the session is saved to the DB. Perhaps there is a place to store  
things in the session that _don’t_ get saved? Or a more general  
app-level caching mechanism?

---

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 25, 2007, 8:53pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/2 "2007-01-25T20:53:19Z")

</div>

This won’t really solve your problem, but you could simplify your  
root\_post method as a ‘has\_one’ association with an order specified:

has\_one :root\_post, :class\_name =\> ‘Post’, :order =\> ‘posted\_at DESC’,  
:conditions =\> ‘parent\_id IS NULL’

This will only load once per model I think - but I am not 100% certain.

---

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 25, 2007, 8:54pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/3 "2007-01-25T20:54:05Z")

</div>

> This will only load once per model I think - but I am not 100% certain.

I meant ‘once per instance’…

---

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 25, 2007, 9:38pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/4 "2007-01-25T21:38:55Z")

</div>

Mark D. wrote:

> This won’t really solve your problem, but you could simplify your  
> root\_post method as a ‘has\_one’ association with an order specified:
> 
> has\_one :root\_post, :class\_name =\> ‘Post’, :order =\> ‘posted\_at DESC’,  
> :conditions =\> ‘parent\_id IS NULL’
> 
> This will only load once per model I think - but I am not 100% certain.

Wouldn’t the condition have to include thread\_id?

---

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 25, 2007, 10:59pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/5 "2007-01-25T22:59:31Z")

</div>

I’m not sure how the Thread model fits into your system. Assuming that  
you have two models:, you can simply do:

–

class Topic \< ActiveRecord::Base

has\_many :posts  
has\_one :root\_post, :class\_name =\> ‘Post’, :conditions =\> ‘parent\_id  
IS NULL’  
has\_many :replies, :class\_name =\> ‘Post’, :offset =\> 2

end

class Post \< ActiveRecord::Base

belongs\_to :topic

end

–

All that is needed to link these up is a ‘topic\_id’ fk in your post  
table.

~ Mark D.

---

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 25, 2007, 11:45pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/6 "2007-01-25T23:45:45Z")

</div>

Mark D. wrote:

> I’m not sure how the Thread model fits into your system. Assuming that  
> you have two models:, you can simply do:
> 
> –
> 
> class Topic \< ActiveRecord::Base
> 
> has\_many :posts  
> has\_one :root\_post, :class\_name =\> ‘Post’, :conditions =\> ‘parent\_id  
> IS NULL’  
> has\_many :replies, :class\_name =\> ‘Post’, :offset =\> 2
> 
> end
> 
> class Post \< ActiveRecord::Base
> 
> belongs\_to :topic
> 
> end
> 
> –
> 
> All that is needed to link these up is a ‘topic\_id’ fk in your post  
> table.
> 
> ~ Mark D.

Thanks.

By ‘Thread’, I meant ‘Topic’.

I’m still curious about the more general case. How do I store  
ActiveRecords in the Session without marshalling problems?

---

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 25, 2007, 10:39pm UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/7 "2007-01-25T22:39:42Z")

</div>

Robert H. wrote:

> Wouldn’t the condition have to include thread\_id?

Or is that implied in has\_one?

---

<div class="post-metadata">

**Author:** ![quik77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/dec6dc/32.png) [@quik77](https://www.ruby-forum.com/u/quik77)\
**Post date:** [January 26, 2007, 3:54am UTC](https://www.ruby-forum.com/t/avoiding-repeated-calls-to-the-db/83413/8 "2007-01-26T03:54:55Z")

</div>

> If I put any ActiveRecord into the session, I get marshalling problems  
> when the session is saved to the DB. Perhaps there is a place to store  
> things in the session that _don’t_ get saved? Or a more general  
> app-level caching mechanism?

The only built-in caching deals with caching the rendered output.  
Folks tend to use something like memcache to cache the actual models  
though. Look at acts\_as\_cached and cached\_model:

acts\_as\_cached

> **[Quickly: returning — err.the\_blog](http://errtheblog.com/post/27)**
>
> Err the Blog: Ruby and Rails from the front.

cached\_model

> **[dev.robotcoop.com](https://www.robotcoop.com/dev-sub/index.html)**
>
> Tools and projects used by The Robot Co-op, Inc.

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