0

Pretend I have a model, Post which has_many :comments. How can I only display posts that have comments?

I am somewhat comfortable with named_scope but I don't know how I can put Post.comments (or self.comments) in the :conditions hash which expects symbols.

class Post < ActiveRecord::Base
     has_many :comments
     named_scope :with_comments, :conditions => [#self.comments.length > 0]
end

What do I write in the commented area?

Thanks!

user94154
  • 16,176
  • 20
  • 77
  • 116

2 Answers2

2

You should be able to just join against your comments table, making sure to select the distinct rows

named_scope :with_comments, :joins => :comments, :select => 'DISTINCT posts.*'
slillibri
  • 731
  • 5
  • 6
  • looks awesome. How can I pass in arguments allowing me to manually enter in attribute names. my posts table has a pk called postid and the comments table has an fk called post_id. I know how to manually set pks and fks in the associations, how do I do it with named_scope? thanks again, this really is a quality response. – user94154 Jun 17 '09 at 00:49
  • Just replace the :joins option with the join you want. You probably want something like the following, :joins => 'INNER JOIN "comments" ON comments.post_id = posts.postid' – slillibri Jun 17 '09 at 22:55
  • In Rails, `:joins` defaults to use `INNER JOIN` – Bart Jedrocha Oct 18 '11 at 01:35
1

Better might be to put a counter_cache on Post.

class Comment < AR:Base
  belongs_to :post, :counter_cache => true
end

Then you only need to do 1 query instead of two.

Post.find(:all, :conditions => ["counter_cache > 0"])

BJ Clark
  • 3,215
  • 2
  • 17
  • 16