# Using includes twice

**URL:** <https://www.ruby-forum.com/t/using-includes-twice/186760>\
**Category:** Rails\
**Created:** [February 25, 2008, 9:14pm UTC](https://www.ruby-forum.com/t/using-includes-twice/186760 "2008-02-25T21:14:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 25, 2008, 9:14pm UTC](https://www.ruby-forum.com/t/using-includes-twice/186760/1 "2008-02-25T21:14:57Z")

</div>

Hello,

Is there a way to handle includes twice?  
Basic models, Group and User.  
Group has many users, users belong to group.  
Users have a ‘role’, which can be manager/developer and stuff like  
that.

Say I want to find all groups that have a manager in them, including  
all users.  
Group.find(:all, :include =\> :users, :conditions =\> [“users.role = ?”,  
‘Manager’]) won’t do the trick, since it will indeed find all groups  
that have managers, but it fails to include all users.  
Of course this is to be expected because of the conditions, but I  
think there must be some way to include users twice in the query, once  
for the conditions, and once as the ‘real output’

Ofcourse I can write it like this:  
managed\_groups\_including\_users =  
User.find\_all\_by\_role(‘Manager’, :include =\> {:group  
=\> :users}).map(&:group).uniq

But that involves 2 operations in memory (mapping and uniq’ing) which  
isn’t nice to do on large datasets.  
Also since it’s the groups I’m after, it doesn’t feel right to start  
asking the User model.

Any thoughts?

Thanks,  
Mathijs

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 26, 2008, 5:54am UTC](https://www.ruby-forum.com/t/using-includes-twice/186760/2 "2008-02-26T05:54:22Z")

</div>

removed\_email\_address@domain.invalid wrote:

> Hello,
> 
> Is there a way to handle includes twice?  
> Basic models, Group and User.  
> Group has many users, users belong to group.  
> Users have a ‘role’, which can be manager/developer and stuff like  
> that.
> 
> Say I want to find all groups that have a manager in them, including  
> all users.  
> Group.find(:all, :include =\> :users, :conditions =\> [“users.role = ?”,  
> ‘Manager’]) won’t do the trick, since it will indeed find all groups  
> that have managers, but it fails to include all users.  
> Of course this is to be expected because of the conditions, but I  
> think there must be some way to include users twice in the query, once  
> for the conditions, and once as the ‘real output’
> 
> Ofcourse I can write it like this:  
> managed\_groups\_including\_users =  
> User.find\_all\_by\_role(‘Manager’, :include =\> {:group  
> =\> :users}).map(&:group).uniq
> 
> But that involves 2 operations in memory (mapping and uniq’ing) which  
> isn’t nice to do on large datasets.  
> Also since it’s the groups I’m after, it doesn’t feel right to start  
> asking the User model.
> 
> Any thoughts?
> 
> Thanks,  
> Mathijs

Group.find\_by\_sql \<\<-END select \* from groups g  
join users u on u.group\_id = g.id  
join users u2 on u2.group\_id = u.group\_id  
where u2.role like ‘manager’  
END

NOT TESTED and I am not on my machine so I can’t test it… but I think  
something along these lines will avoid using the users twice… I give  
no guarantees as to how this will scale as I think it may be a NxN  
problem ☹

Anyways, let me know if your db blows up…

ilan

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 26, 2008, 8:54am UTC](https://www.ruby-forum.com/t/using-includes-twice/186760/3 "2008-02-26T08:54:56Z")

</div>

Hi Ilian,

Thanks for your help,  
this is what happens:

> > gs=Group.find\_by\_sql “select \* from groups g join users u on u.group\_id = g.id join users u2 on u2.group\_id = u.group\_id where u2.role like ‘manager’”  
> > =\> [#\<Group id: 2, name: “Richard”, created\_at: “2008-02-25 21:09:39”,  
> > updated\_at: “2008-02-25 21:09:39”\>, #\<Group id: 2, name: “Richard”,  
> > created\_at: “2008-02-25 21:09:39”, updated\_at: “2008-02-25 21:09:39”\>]
> 
> > gs[0]  
> > =\> #\<Group id: 2, name: “Richard”, created\_at: “2008-02-25 21:09:39”,  
> > updated\_at: “2008-02-25 21:09:39”\>
> 
> > Group.find(2)  
> > =\> #\<Group id: 2, name: “Managers”, created\_at: “2008-02-25 21:08:35”,  
> > updated\_at: “2008-02-25 21:08:35”\>

I believe AR chokes on the “extra” attributes that get brought back.  
Ofcourse this could be fixed by naming attributes explicitly, but  
another this AR won’t do on find\_by\_sql (according to api docs) is  
create associations with the extra data.

as seen by:

> > gs[0].users  
> > which will fetch data again:  
> > User Load (0.000486) SELECT \* FROM users WHERE (users.group\_id =

1. 

So I think using ray SQL in this case is not an option.
