# A Better Way Idiom here

**URL:** <https://www.ruby-forum.com/t/a-better-way-idiom-here/83709>\
**Category:** Rails\
**Created:** [January 29, 2007, 3:32am UTC](https://www.ruby-forum.com/t/a-better-way-idiom-here/83709 "2007-01-29T03:32:59Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![corywilkerson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/aca169/32.png) [@corywilkerson](https://www.ruby-forum.com/u/corywilkerson)\
**Post date:** [January 29, 2007, 3:32am UTC](https://www.ruby-forum.com/t/a-better-way-idiom-here/83709/1 "2007-01-29T03:32:59Z")

</div>

Hello again!

Ok, I’m thinking that ‘find’ has a condition I can throw in here but I’m  
just not familiar with using associations in find conditions (I could  
just use raw SQL but that kills the beauty of this whole thing). Also,  
I’d like to move less data across the wire and this approach requires  
all data to be present…

So, that said.

Imagine a scenario where you have a Director that may or not have yet  
directed a Movie. I’m wanting to return Directors to the view that have  
AT least one movie. Here’s my hack:

@directors = Director.find(:all).delete\_if {|director|  
director.movies.count == 0  
}

I’m certain there’s a better way.

---

<div class="post-metadata">

**Author:** ![corywilkerson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/aca169/32.png) [@corywilkerson](https://www.ruby-forum.com/u/corywilkerson)\
**Post date:** [January 29, 2007, 6:55am UTC](https://www.ruby-forum.com/t/a-better-way-idiom-here/83709/2 "2007-01-29T06:55:48Z")

</div>

On Jan 28, 2007, at 9:32 PM, Cory W. wrote:

> Ok, I’m thinking that ‘find’ has a condition I can throw in here  
> but I’m  
> just not familiar with using associations in find conditions (I could  
> just use raw SQL but that kills the beauty of this whole thing).  
> Also,  
> I’d like to move less data across the wire and this approach requires  
> all data to be present…

it sounds like you want to do a select, e.g.

@directors = Director.find(:all).select {|director| !(0 ==  
director.movies.count)}

-faisal

---

<div class="post-metadata">

**Author:** ![corywilkerson](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/aca169/32.png) [@corywilkerson](https://www.ruby-forum.com/u/corywilkerson)\
**Post date:** [January 29, 2007, 10:31am UTC](https://www.ruby-forum.com/t/a-better-way-idiom-here/83709/3 "2007-01-29T10:31:14Z")

</div>

> @directors = Director.find(:all).select {|director| !(0 ==  
> director.movies.count)}  
> This method is still going to pull all of the directors from the  
> database before filtering. I’d favour a more SQL heavy approach:

Director.find(:all, :joins =\> ‘inner join movies on movies.director\_id  
= directors.id’, :group =\> ‘directors.id’)

SQL would naturally filter out the directors with no movies as the  
inner join requires the director to exist in the movies table. You  
then group the results so you just get the directors and not the  
associated movies.

This is obviously more verbose than a straight find(:all) but you can  
just add a method to your model. If you find yourself using this  
across a few of your models, you can try and create a method you can  
use to extend active record.

Hope that helps,

Steve
