# Dynamic finders in has\_many associations

**URL:** <https://www.ruby-forum.com/t/dynamic-finders-in-has-many-associations/135725>\
**Category:** Rails\
**Created:** [April 24, 2008, 2:07pm UTC](https://www.ruby-forum.com/t/dynamic-finders-in-has-many-associations/135725 "2008-04-24T14:07:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![pahagon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ac8455/32.png) [@pahagon](https://www.ruby-forum.com/u/pahagon)\
**Post date:** [April 24, 2008, 2:07pm UTC](https://www.ruby-forum.com/t/dynamic-finders-in-has-many-associations/135725/1 "2008-04-24T14:07:35Z")

</div>

I have these 3 models.

class Ivr \< ActiveRecord::Base  
has\_many :klusterings, :dependent =\> :destroy  
has\_many :klusters, :through =\> :klusterings, :uniq =\> true  
end

class Kluster \< ActiveRecord::Base  
has\_many :klusterings, :dependent =\> :destroy  
has\_many :ivrs, :through =\> :klusterings, :uniq =\> true  
end

class Klustering \< ActiveRecord::Base  
belongs\_to :kluster  
belongs\_to :ivr  
end

I faced 2 problems and didn’t manage to find any good tutorial.

1. Given some Kluster A, I want to find all the Ivrs that aren’t in A.
2. I want to find all the Ivrs that aren’t in ANY Kluster.

– I managed to do 1. with:  
@kluster = Kluster.find(params[:id])  
@all\_ivrs = Ivr.find(:all)

@ivrs = (@all\_ivrs - @kluster.ivrs)

– And I did 2. with:  
@all\_ivrs = Ivr.find(:all).select{ |ivr| ivr.klusters.empty? }

But 1. does two SQL queries, one possibly very big (Ivr.find(:all)).  
And 2. does that too.

Any way to do this, preferibly with dynamic finders?

---

<div class="post-metadata">

**Author:** ![pahagon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ac8455/32.png) [@pahagon](https://www.ruby-forum.com/u/pahagon)\
**Post date:** [April 24, 2008, 2:16pm UTC](https://www.ruby-forum.com/t/dynamic-finders-in-has-many-associations/135725/2 "2008-04-24T14:16:24Z")

</div>

On 24 Apr 2008, at 13:06, Paulo P. wrote:

> I have these 3 models.
> 
> 1. Given some Kluster A, I want to find all the Ivrs that aren’t in A.
> 2. I want to find all the Ivrs that aren’t in ANY Kluster.

You need some lower level stuff:

Ivr.find :all, :joins =\> ‘left outer join klusterings on  
klusterings.ivr\_id = ivrs.id’, :conditions =\> ‘kluster\_id IS NULL’  
finds ivrs associated with no klusters  
Ivr.find :all, :joins =\> “left outer join klusterings on  
klusterings.ivr\_id = ivrs.id AND kluster\_id =  
#{@kluster.id}”, :conditions =\> ‘kluster\_id IS NULL’  
should find the ivrs not associated with @kluster  
(typed quickly in mail, so might be slightly off, but should get you  
there in the end)

Fred

---

<div class="post-metadata">

**Author:** ![pahagon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/ac8455/32.png) [@pahagon](https://www.ruby-forum.com/u/pahagon)\
**Post date:** [April 24, 2008, 6:59pm UTC](https://www.ruby-forum.com/t/dynamic-finders-in-has-many-associations/135725/3 "2008-04-24T18:59:41Z")

</div>

I’ve done some similar lookups along these lines…

> 1. Given some Kluster A, I want to find all the Ivrs that aren’t in A.  
> @kluster = Kluster.find(…A…)  
> @ivrs = Ivr.find(:all, :conditions=\>[“id not in (?)”,  
> @kluster.ivr\_ids.join(‘,’)])

> 1. I want to find all the Ivrs that aren’t in ANY Kluster.  
> ivr\_ids = Kluster.find(:all).collect{|kluster| kluster.ivr\_ds}.uniq  
> @unklustered = Ivr.find(:all, :conditions=\>[“id not in (?)”,  
> ivr\_ids.join(‘,’)])

On Apr 24, 8:15 am, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
