views:

197

answers:

3

Eager loading is nice with the include attribute

Post.find(:all, :include => :author)

I'm wondering if you can also eager load counts, like if I wanted to get the number of comments for each post, without loading all the comments themselves?

Maybe something like

Post.find(:all, :include => [:author, "count(comments)")

I suppose I could use a count_cache column. But doing it all in an include would be really beautiful, if it's possible.

Extra bonus points if someone can show how to not only get the count, but put some conditions too, like count of only posts which have been approved.

A: 

they should already be loaded use

post.comments.length

I was having this same problem because I was using .count

Christopher
I don't think this is what he is looking for. This will load all the entries in the comments association and then count them. He wants to use SQL to eagerly pull the count without loading the objects. (Or at least that's how I understand it).
Mike
You're right Mike.
Brian Armstrong
A: 

Try this:

Comment.count(:group => :post)

To filter by conditions:

Comment.count(:group => :post, :conditions => {:approved => true })

These will return hashes with posts as keys and the number of comments as values.

avaynshtok
It's not exactly what I'm looking for. Yes, you can do it in a separate call like this. But I don't think you can do them in an association like I wanted. Probably have to use count_cache column.
Brian Armstrong
+1  A: 

In MySQL at least, it is faster to do these as two separate calls because you get to avoid the join. I know this doesn't answer your question, but it seems like you're trying to get better speed and doing

Post.find ...

Then

post.comments.count

Is faster and more memory efficient (for the database) than if you retrieve both in one query.

Drew Blas