# How to do "special queries" ala The Rails Way on "associated" conditions?

**URL:** <https://www.ruby-forum.com/t/how-to-do-special-queries-ala-the-rails-way-on-associated-conditions/155539>\
**Category:** Rails\
**Created:** [December 13, 2008, 5:21am UTC](https://www.ruby-forum.com/t/how-to-do-special-queries-ala-the-rails-way-on-associated-conditions/155539 "2008-12-13T05:21:57Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lunaclaire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f4b2a3/32.png) [@lunaclaire](https://www.ruby-forum.com/u/lunaclaire)\
**Post date:** [December 13, 2008, 5:21am UTC](https://www.ruby-forum.com/t/how-to-do-special-queries-ala-the-rails-way-on-associated-conditions/155539/1 "2008-12-13T05:21:57Z")

</div>

I have the following in a model class:

class Game \< ActiveRecord::Base  
has\_many :player\_stats  
has\_many :players, :through =\> :player\_stats

def visitor\_stats  
stats = []  
player\_stats.each do |stat|  
stats \<\< stat if stat.player.team.team\_code ==  
self.visiting\_team\_code  
end  
stats  
end

def home\_stats  
stats = []  
player\_stats.each do |stat|  
stats \<\< stat if stat.player.team.team\_code ==  
self.home\_team\_code  
end  
stats  
end  
end

I understand that this isn’t the most efficient or elegant way to do  
things. I gleaned this most recently from the posting at (see his  
Case 3):

[http://www.therailsway.com/tags/has\_many](http://www.therailsway.com/tags/has_many)

So, I would like to do something like the following, but I’m having a  
problem with the conditions:

has\_many :visitor\_stats, :class\_name=\>“PlayerStat”, :conditions=\>  
\<what???\>

the condition here should be something matching “player.team.team\_code  
== self.visiting\_team\_code” in the code I have now.

has\_many :home\_stats, :class\_name=\>“PlayerStat”, :conditions=\>  
\<what???\>

and here it should be something matching “player.team.team\_code ==  
self.home\_team\_code” in the existing code.

The conditions specified need to be something that could go in a SQL  
statement, right? How would I make the conditions work thru the  
associations of a PlayerStat belonging to a Player belonging to a Team  
which has a team\_code. And matching it to this Game’s  
visiting\_team\_code or home\_team\_code

---

<div class="post-metadata">

**Author:** ![lunaclaire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f4b2a3/32.png) [@lunaclaire](https://www.ruby-forum.com/u/lunaclaire)\
**Post date:** [December 18, 2008, 1:51am UTC](https://www.ruby-forum.com/t/how-to-do-special-queries-ala-the-rails-way-on-associated-conditions/155539/2 "2008-12-18T01:51:04Z")

</div>

lunaclaire wrote:

> self.visiting\_team\_code  
> end
> 
> self.home\_team\_code" in the existing code.
> 
> The conditions specified need to be something that could go in a SQL  
> statement, right? How would I make the conditions work thru the  
> associations of a PlayerStat belonging to a Player belonging to a Team  
> which has a team\_code. And matching it to this Game’s  
> visiting\_team\_code or home\_team\_code

I don’t think what you need can be formulated into normal has\_manys.  
You’ll either have to use the has\_many :finder\_sql option that  
includes joins to the players and teams tables, allowing you to  
add the appropriate SQL conditions, or you can keep visitor\_stats  
and home\_stats as methods, but have them call find:

def home\_stats  
player\_stats.find :all, :select =\> ‘player\_stats.\*’,  
:joins =\> {:player =\> :team},  
:conditions =\> “teams.team\_code =  
#{home\_team\_code}”  
end

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)

---

<div class="post-metadata">

**Author:** ![lunaclaire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f4b2a3/32.png) [@lunaclaire](https://www.ruby-forum.com/u/lunaclaire)\
**Post date:** [December 18, 2008, 4:14am UTC](https://www.ruby-forum.com/t/how-to-do-special-queries-ala-the-rails-way-on-associated-conditions/155539/3 "2008-12-18T04:14:26Z")

</div>

Thanks for the reply, Mark.

One of the assertions in that RailsWay posting was that by using the  
has\_many approach, I’d gain efficiency because of caching. I don’t  
understand enough about caching yet to see why, but let me ask this  
about using your approach… would the code you show with the :joins  
clause be more or less efficient than the code I have above in my  
current home\_stats method?

---

<div class="post-metadata">

**Author:** ![lunaclaire](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/f4b2a3/32.png) [@lunaclaire](https://www.ruby-forum.com/u/lunaclaire)\
**Post date:** [December 18, 2008, 5:02am UTC](https://www.ruby-forum.com/t/how-to-do-special-queries-ala-the-rails-way-on-associated-conditions/155539/4 "2008-12-18T05:02:23Z")

</div>

lunaclaire wrote:

> Thanks for the reply, Mark.
> 
> One of the assertions in that RailsWay posting was that by using the  
> has\_many approach, I’d gain efficiency because of caching. I don’t  
> understand enough about caching yet to see why, but let me ask this  
> about using your approach… would the code you show with the :joins  
> clause be more or less efficient than the code I have above in my  
> current home\_stats method?

Your original code becomes more efficient if:

- Both visitor and home stats are often used together in the same  
request
- The collections are small

But because you were not pre-loading the the player and team  
associations using :include, what you had is very inefficient.  
Each time round each loop a DB fetch is being made for the  
player of a stat record and the team of a player record.

You could add caching to the method I posted:

def home\_stats(reload = false)  
@home\_stats = nil if reload  
@home\_stats ||= player\_stats.find …  
end

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)
