A Better Way Idiom here

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.

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

@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