# ActiveRecords Eager Loading

**URL:** <https://www.ruby-forum.com/t/activerecords-eager-loading/123787>\
**Category:** Rails\
**Created:** [December 20, 2007, 5:14pm UTC](https://www.ruby-forum.com/t/activerecords-eager-loading/123787 "2007-12-20T17:14:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![betame342](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/90db22/32.png) [@betame342](https://www.ruby-forum.com/u/betame342)\
**Post date:** [December 20, 2007, 5:14pm UTC](https://www.ruby-forum.com/t/activerecords-eager-loading/123787/1 "2007-12-20T17:14:51Z")

</div>

Hi,

## I am doing an eager loading in ruby on rails using below statement

```
 Article.find(:all, :include => [:asset, :vote],
              :conditions=>"assets.parent_id is null",
              :order=>"stat_final_ranking desc", :limit=>20)

```

* * *

the above statement resulted in this expensive query. After indexing, it  
take about 3 seconds to execute. (before indexing it is about 25  
seconds)

## SELECT DISTINCT articles.id FROM articles LEFT OUTER JOIN assets ON assets.attachable\_id = articles.id AND assets.attachable\_type = ‘Article’ LEFT OUTER JOIN votes ON votes.voteable\_id = articles.id AND votes.voteable\_type = 'Article’AND user\_id = 2 WHERE (assets.parent\_id is null) ORDER BY stat\_final\_ranking desc LIMIT 20

so, what I plan to do it is to cache the expensive query without  
including vote table  
Article.find(:all, :include =\> [:asset],  
:conditions=\>“assets.parent\_id is null”,  
:order=\>“stat\_final\_ranking desc”, :limit=\>20)

then later combine it with vote table which is different for each user.

Is the method to cache the expensive query the right approach?

Also, I have another question how to combine @articles and @vote after  
getting it from database.  
@articles= Article.find(:all, :include =\> [:asset],  
:conditions=\>“assets.parent\_id is null”,  
:order=\>“stat\_final\_ranking desc”, :limit=\>20)  
with  
@votes = Vote.find(:all, :conditions=\> “user\_id” …

Thanks in advance,

---

<div class="post-metadata">

**Author:** ![betame342](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/90db22/32.png) [@betame342](https://www.ruby-forum.com/u/betame342)\
**Post date:** [December 21, 2007, 4:26am UTC](https://www.ruby-forum.com/t/activerecords-eager-loading/123787/2 "2007-12-21T04:26:29Z")

</div>

Beta B. wrote:

> seconds)  
> One way forward with this non-caching option would be to  
> only load the votes of the current user. This can be done  
> with a trick that dynamically sets the :conditions option on  
> the vote association.

> Also, I have another question how to combine @articles and @vote after  
> getting it from database.  
> @articles= Article.find(:all, :include =\> [:asset],  
> :conditions=\>“assets.parent\_id is null”,  
> :order=\>“stat\_final\_ranking desc”, :limit=\>20)  
> with  
> @votes = Vote.find(:all, :conditions=\> “user\_id” …

You want the votes to be hashed by article id, which the above would  
not give you unless you hashed it after retrieval.

The alternative is to do an Article query like your original one,  
but leaving out the asset association, and, for speed, only selecting  
the id of the article model. Now you can include the user\_id  
condition because don’t care if the articles the user hasn’t voted  
for are dropped.

Id-only selection would however require use of plugins that allow use of  
the find :select option in combination with eager loading of the votes.

–  
We develop, watch us RoR, in numbers too big to ignore.

---

<div class="post-metadata">

**Author:** ![betame342](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/90db22/32.png) [@betame342](https://www.ruby-forum.com/u/betame342)\
**Post date:** [December 21, 2007, 8:09am UTC](https://www.ruby-forum.com/t/activerecords-eager-loading/123787/3 "2007-12-21T08:09:55Z")

</div>

Thanks Mark for the feedback,

you did bring good point in “id-only selection”.

Here is what I am trying to achieve:  
Article1 – Vote1(by current user)  
Asset1, Asset2, Asset3  
Article2 – Vote2 (by current user)  
Asset3, Asset4

I did have eager loading query to only load votes of the current user.  
So that’s why I want to separate it out. Article and assets most likely  
will stay the same and it is good candidate to cache it. However, votes  
by user will keep changing.

If I use this method, I still need to figure out how to combine the  
cache (Article and Assets) with the votes for current user.

> The alternative is to do an Article query like your original one,  
> but leaving out the asset association, and, for speed, only selecting  
> the id of the article model. Now you can include the user\_id  
> condition because don’t care if the articles the user hasn’t voted  
> for are dropped.

for your alternative, If I leave out the Assets, I will not be able to  
get the asset arrays. I think it is pretty late night right now. May be  
tomorrow, I will get more ideas. 🙂

Thanks again for the feedback

---

<div class="post-metadata">

**Author:** ![betame342](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/90db22/32.png) [@betame342](https://www.ruby-forum.com/u/betame342)\
**Post date:** [December 22, 2007, 6:18pm UTC](https://www.ruby-forum.com/t/activerecords-eager-loading/123787/4 "2007-12-22T18:18:08Z")

</div>

Mark Reginald J. wrote:

> The alternative is to do an Article query like your original one,  
> but leaving out the asset association, and, for speed, only selecting  
> the id of the article model. Now you can include the user\_id  
> condition because don’t care if the articles the user hasn’t voted  
> for are dropped.
> 
> Id-only selection would however require use of plugins that allow use of  
> the find :select option in combination with eager loading of the votes.

Now your alternative make sense. It speed up the performance a lot.

Thanks again,  
Beta
