# Eager loading is letting me down

**URL:** <https://www.ruby-forum.com/t/eager-loading-is-letting-me-down/156786>\
**Category:** Rails\
**Created:** [January 2, 2009, 9:52pm UTC](https://www.ruby-forum.com/t/eager-loading-is-letting-me-down/156786 "2009-01-02T21:52:30Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![taylorstrait](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5a626/32.png) [@taylorstrait](https://www.ruby-forum.com/u/taylorstrait)\
**Post date:** [January 2, 2009, 9:52pm UTC](https://www.ruby-forum.com/t/eager-loading-is-letting-me-down/156786/1 "2009-01-02T21:52:30Z")

</div>

Class User has\_many Referrals. Referrals have an instance variable  
‘point\_value.’ So on my users/index action I want to list the user  
info, total referrals, and then total points. However, I am getting the  
notorious N+1 problem when running this action.

USERS CONTROLLER  
def index  
@users = User.find(:all, :include =\> :referrals)  
end

INDEX VIEW  
\<% for user in @users %\>

 \<%= h user.email %\> Referrals: \<%= user.referrals.size %\> Points: \<%= user.total\_points %\>

USER.RB MODEL  
has\_many :referrals,  
:foreign\_key =\> “referer\_id”

def total\_points  
self.referrals.sum :point\_value  
end

The index action nails me with a nasty N+2 queries (i have six user  
records in the test db):

Processing UsersController#index (for 127.0.0.1 at 2009-01-02 15:49:16)  
[GET]  
User Load (4.3ms) SELECT \* FROM “users”  
Referral Load (1.4ms) SELECT “referrals”.\* FROM “referrals” WHERE  
(“referrals”.referer\_id IN (1,2,3,4,6,7))  
Rendering template within layouts/users  
Rendering users/index  
SQL (0.3ms) SELECT sum(“referrals”.point\_value) AS sum\_point\_value  
FROM “referrals” WHERE (“referrals”.referer\_id = 1)  
SQL (0.3ms) SELECT sum(“referrals”.point\_value) AS sum\_point\_value  
FROM “referrals” WHERE (“referrals”.referer\_id = 2)  
SQL (0.3ms) SELECT sum(“referrals”.point\_value) AS sum\_point\_value  
FROM “referrals” WHERE (“referrals”.referer\_id = 3)  
SQL (0.2ms) SELECT sum(“referrals”.point\_value) AS sum\_point\_value  
FROM “referrals” WHERE (“referrals”.referer\_id = 4)  
SQL (0.3ms) SELECT sum(“referrals”.point\_value) AS sum\_point\_value  
FROM “referrals” WHERE (“referrals”.referer\_id = 6)  
SQL (0.3ms) SELECT sum(“referrals”.point\_value) AS sum\_point\_value  
FROM “referrals” WHERE (“referrals”.referer\_id = 7)

Is this a failing of the rails .sum method to look inside the collection  
or am I doing something wrong?

---

<div class="post-metadata">

**Author:** ![taylorstrait](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5a626/32.png) [@taylorstrait](https://www.ruby-forum.com/u/taylorstrait)\
**Post date:** [January 2, 2009, 10:07pm UTC](https://www.ruby-forum.com/t/eager-loading-is-letting-me-down/156786/2 "2009-01-02T22:07:34Z")

</div>

Fixed. The short version of the story is that rails’ .sum helper hits  
the DB N+1 times. Writing a custom sum method solves this problem. In  
my case, the top method only hits the DB twice whereas the second method  
hits the DB N+2 times.

# 2 queries

def total\_points  
sum = 0  
self.referrals.each {|ref| sum += ref.point\_value}  
sum  
end

# N+2 queries

def total\_points  
self.referrals.sum :point\_value  
end

So :include DOES work as long as you are careful to manipulate the  
collection in ruby and not use another ActiveRecord method to do  
summation.

---

<div class="post-metadata">

**Author:** ![taylorstrait](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5a626/32.png) [@taylorstrait](https://www.ruby-forum.com/u/taylorstrait)\
**Post date:** [January 2, 2009, 10:38pm UTC](https://www.ruby-forum.com/t/eager-loading-is-letting-me-down/156786/3 "2009-01-02T22:38:58Z")

</div>

You probably could have said:

def total\_points  
self.referrals.to\_a.sum(&:point\_value)  
end

And then #sum is from Enumerable (as extended by ActiveSupport) rather  
than ActiveRecord::Calculations::ClassMethods (note the use of .to\_a  
in there to get a real array rather than an association proxy)

-Rob

On Jan 2, 2009, at 4:07 PM, Taylor S. wrote:

> ## sum = 0 collection in ruby and not use another ActiveRecord method to do summation.
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> >

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid  
+1 513-295-4739  
Skype: rob.biedenharn
