# Always use eager loading on a specific model?

**URL:** <https://www.ruby-forum.com/t/always-use-eager-loading-on-a-specific-model/130526>\
**Category:** Rails\
**Created:** [February 29, 2008, 1:53am UTC](https://www.ruby-forum.com/t/always-use-eager-loading-on-a-specific-model/130526 "2008-02-29T01:53:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![adam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4af34b/32.png) [@adam](https://www.ruby-forum.com/u/adam)\
**Post date:** [February 29, 2008, 1:53am UTC](https://www.ruby-forum.com/t/always-use-eager-loading-on-a-specific-model/130526/1 "2008-02-29T01:53:31Z")

</div>

Let’s say I’ve got the following models:

Book  
MyBook  
User  
Author

Where books and user has\_many :through =\> my\_books, author has\_many  
books, and books belongs\_to author and user.

If books/index showed me all of the books with each author’s name, I  
could use eager loading like so:

@books = Book.find(:all, :include =\> :author)

So that when I iterate through a hundred books and authors, I’ve  
already loaded the author. If I want to do the same, but with my\_books/  
index, I don’t know how to include :author, b/c it looks like this:

@books = current\_user.books

I’ll get all the the books, but I’ll have to load all the authors for  
each song. The same is true if I were to use:

@books = MyBook.find\_all\_by\_user\_id(current\_user, :include =\> song)

Which means that when I’m iterating through books, I have to hit the  
database every for every book to get its author. Is there any way to  
use eager loading for models once removed, like author is in this  
example? (i.e., User -\> Book -\> Author or MyBook -\> Book -\> Author)

Hopefully I got that all across. Is there a better way?

---

<div class="post-metadata">

**Author:** ![adam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4af34b/32.png) [@adam](https://www.ruby-forum.com/u/adam)\
**Post date:** [February 29, 2008, 2:11am UTC](https://www.ruby-forum.com/t/always-use-eager-loading-on-a-specific-model/130526/2 "2008-02-29T02:11:41Z")

</div>

Adam wrote:

> Let’s say I’ve got the following models:

> Hopefully I got that all across. Is there a better way?

AFAIK, eager loading does not work past one db relation. If this would  
be possible, imagine the load it would put on your db. Your options  
are:

1. find\_by\_sql
2. create a view in your db that goes across the relations and make a  
first class model on top
3. use find() but with a huge :join clause that will make your code next  
to unreadable.
4. rethink your relations, as you have them now, a book can’t have more  
than one author
5. rethink how you want to access your models.

hth

ilan

---

<div class="post-metadata">

**Author:** ![adam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4af34b/32.png) [@adam](https://www.ruby-forum.com/u/adam)\
**Post date:** [February 29, 2008, 2:49am UTC](https://www.ruby-forum.com/t/always-use-eager-loading-on-a-specific-model/130526/3 "2008-02-29T02:49:32Z")

</div>

Adam wrote:

> Let’s say I’ve got the following models:
> 
> Book  
> MyBook  
> User  
> Author
> 
> Where books and user has\_many :through =\> my\_books, author has\_many  
> books, and books belongs\_to author and user.
> 
> If books/index showed me all of the books with each author’s name, I  
> could use eager loading like so:
> 
> @books = Book.find(:all, :include =\> :author)
> 
> So that when I iterate through a hundred books and authors, I’ve  
> already loaded the author. If I want to do the same, but with my\_books/  
> index, I don’t know how to include :author, b/c it looks like this:
> 
> @books = current\_user.books
> 
> I’ll get all the the books, but I’ll have to load all the authors for  
> each song. The same is true if I were to use:
> 
> @books = MyBook.find\_all\_by\_user\_id(current\_user, :include =\> song)
> 
> Which means that when I’m iterating through books, I have to hit the  
> database every for every book to get its author. Is there any way to  
> use eager loading for models once removed, like author is in this  
> example? (i.e., User -\> Book -\> Author or MyBook -\> Book -\> Author)
> 
> Hopefully I got that all across. Is there a better way?

You can include in an association.

class ForumPost \< ActiveRecord::Base  
belongs\_to :forum  
belongs\_to :person  
belongs\_to :parent\_post, :class\_name =\> ‘ForumPost’, :foreign\_key =\>  
‘parent\_id’  
has\_one :most\_recent\_reply, :class\_name =\> ‘ForumPost’, :foreign\_key  
=\> ‘parent\_id’, :order =\> ‘created\_at desc’, :include =\> :person  
has\_many :replies, :class\_name =\> ‘ForumPost’, :foreign\_key =\>  
‘parent\_id’, :include =\> :person, :order =\> ‘created\_at’

Notice the has\_one :most\_recent\_reply and has\_many :replies. So when you  
do current\_user.books, if you have

has\_many :books, :include =\> :author

it _should_ work like you want.

Peace,  
Phillip

---

<div class="post-metadata">

**Author:** ![adam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4af34b/32.png) [@adam](https://www.ruby-forum.com/u/adam)\
**Post date:** [March 1, 2008, 2:12am UTC](https://www.ruby-forum.com/t/always-use-eager-loading-on-a-specific-model/130526/4 "2008-03-01T02:12:19Z")

</div>

Oh wow, I didn’t realize you could use :include in the associations,  
that does the trick perfectly. Thanks Phillip!

On Feb 28, 5:49 pm, Phillip K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
