# Find\_by\_ always uses sql?

**URL:** <https://www.ruby-forum.com/t/find-by-always-uses-sql/112161>\
**Category:** Rails\
**Created:** [August 15, 2007, 11:58pm UTC](https://www.ruby-forum.com/t/find-by-always-uses-sql/112161 "2007-08-15T23:58:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ldk2005](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/d9b06d/32.png) [@ldk2005](https://www.ruby-forum.com/u/ldk2005)\
**Post date:** [August 15, 2007, 11:58pm UTC](https://www.ruby-forum.com/t/find-by-always-uses-sql/112161/1 "2007-08-15T23:58:38Z")

</div>

Hi,

If I eagerly load a collection during the initial find, do scoped  
find\_by\_ calls later _always_ use sql?

What is the best pattern to use to not do another db trip?  
Is there some specialized rails method to handle this case?

eg  
Author  
has\_many :books

larry = Author.find\_by\_name(‘larry’, :include =\> :books)

ruby = larry.books.find\_by\_title(‘Ruby’) # does this ALWAYS do a db  
call?

# Is the following the best way to get the one (or nil) book?

temp = larry.books.select{|book| book.title == ‘ruby’}  
ruby = temp.size == 1 ? temp[0] : nil

Thank you for your comments and time,

Larry

---

<div class="post-metadata">

**Author:** ![ldk2005](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/d9b06d/32.png) [@ldk2005](https://www.ruby-forum.com/u/ldk2005)\
**Post date:** [August 17, 2007, 11:56am UTC](https://www.ruby-forum.com/t/find-by-always-uses-sql/112161/2 "2007-08-17T11:56:29Z")

</div>

Larry K. wrote:

> If I eagerly load a collection during the initial find, do scoped  
> find\_by\_ calls later _always_ use sql?

Yes.

> call?
> 
> # Is the following the best way to get the one (or nil) book?
> 
> temp = larry.books.select{|book| book.title == ‘ruby’}  
> ruby = temp.size == 1 ? temp[0] : nil

Yes. Or ruby = larry.books.detect {|book| book.title == ‘ruby’}

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

---

<div class="post-metadata">

**Author:** ![ldk2005](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/d9b06d/32.png) [@ldk2005](https://www.ruby-forum.com/u/ldk2005)\
**Post date:** [August 20, 2007, 6:32am UTC](https://www.ruby-forum.com/t/find-by-always-uses-sql/112161/3 "2007-08-20T06:32:34Z")

</div>

Larry K. wrote:

> Hi,
> 
> If I eagerly load a collection during the initial find, do scoped  
> find\_by\_ calls later _always_ use sql?
> 
> What is the best pattern to use to not do another db trip?  
> Is there some specialized rails method to handle this case?
> 
> eg  
> Author  
> has\_many :books
> 
> larry = Author.find\_by\_name(‘larry’, :include =\> :books)
> 
> ruby = larry.books.find\_by\_title(‘Ruby’) # does this ALWAYS do a db  
> call?
> 
> # Is the following the best way to get the one (or nil) book?
> 
> temp = larry.books.select{|book| book.title == ‘ruby’}  
> ruby = temp.size == 1 ? temp[0] : nil
> 
> Thank you for your comments and time,
> 
> Larry

Sense you now have all Larry’s books in memory it is probably better to  
search through the memory using ruby calls like:

ruby = larry.books.detect {|book| book.title == ‘ruby’}

On the other hand ruby is a comparatively slow next most database  
engines. If you have a large number of books by Larry (or authors in  
general) AND you know you only need to find a small finite set of them  
(like one) The database may be faster then the Ruby script interrupter  
at doing what it does best – finding a subset of items in a table.  
Eager loading is best used when you know you will need all or most of  
the related information in another table, (eg All the books Larry wrote)  
or information in a related table for every member of the first. (eg,  
the best selling book for each Author)

---

<div class="post-metadata">

**Author:** ![ldk2005](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/d9b06d/32.png) [@ldk2005](https://www.ruby-forum.com/u/ldk2005)\
**Post date:** [August 17, 2007, 11:45pm UTC](https://www.ruby-forum.com/t/find-by-always-uses-sql/112161/4 "2007-08-17T23:45:10Z")

</div>

Hi Mark,

Thanks for your time, much appreciated.

> Yes. Or ruby = larry.books.detect {|book| book.title == ‘ruby’}

Regards,

Larry

---

<div class="post-metadata">

**Author:** ![ldk2005](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/d9b06d/32.png) [@ldk2005](https://www.ruby-forum.com/u/ldk2005)\
**Post date:** [August 20, 2007, 2:05pm UTC](https://www.ruby-forum.com/t/find-by-always-uses-sql/112161/5 "2007-08-20T14:05:44Z")

</div>

Hi –

On Mon, 20 Aug 2007, John M. wrote:

> > temp = larry.books.select{|book| book.title == ‘ruby’}  
> > ruby = temp.size == 1 ? temp[0] : nil
> > 
> > Thank you for your comments and time,
> > 
> > Larry
> 
> Sense you now have all Larry’s books in memory it is probably better to  
> search through the memory using ruby calls like:
> 
> ruby = larry.books.detect {|book| book.title == ‘ruby’}

find and find\_by\_\* on a collection are smart, though: they get rolled  
into one database query with the collection query itself. For  
example:

$ ./script/console  
Loading development environment.

> > f = Food.find(:first)  
> > =\> #\<Food:0x3544f04 @attributes={“name”=\>“bread”, “id”=\>“1”,  
> > “food\_group\_id”=\>“2”}\>  
> > f.ingredients.find\_by\_description(“flour”)  
> > =\> #\<Ingredient:0x3523c28 @attributes={“id”=\>“3”,  
> > “description”=\>“flour”, “food\_id”=\>“1”}\>

Here’s the query log:

Food Load (0.000726) SELECT \* FROM foods LIMIT 1  
Ingredient Load (0.000394) SELECT \* FROM ingredients WHERE  
(ingredients.food\_id = 1) AND (ingredients.“description” = ‘flour’)  
LIMIT 1

Notice how the second select combines two where clauses, so the whole  
collection isn’t loaded into memory.

The find\_by\_\* methods have some overhead, though, since they have to  
pass through method\_missing. You can also do:

f.ingredients.find(:first, :conditions =\> “description = ‘flour’”)

which won’t have that overhead. Of course, find\_by\_\* is nice and  
concise, so it’s OK for cases where you’re not looking to tweak  
performance.

David

–

- Books:  
RAILS ROUTING (new! [http://www.awprofessional.com/title/0321509242](http://www.awprofessional.com/title/0321509242))  
RUBY FOR RAILS ([Ruby for Rails](http://www.manning.com/black))
- Ruby/Rails training  
& consulting: Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))
