Search code examples
ruby-on-railsactiverecordruby-on-rails-2named-scope

Using named_scope with counts of child models


I have a simple parent object having many children. I'm trying to figure out how to use a named scope for bringing back just parents with specific numbers of children.

Is this possible?

class Foo < ActiveRecord::Base
    has_many :bars
    named_scope :with_no_bars, ... # count of bars == 0
    named_scope :with_one_bar, ... # count of bars == 1
    named_scope :with_more_than_one_bar, ... # count of bars > 1
end

class Bar < ActiveRecord::Base
    belongs_to :foo
end

I'm hoping to do something like Foo.with_one_bar

I could write methods on the parent class for something like this, but I'd rather have the power of the named scope


Solution

  • class Foo < ActiveRecord::Base
      has_many :bars
    
      # I don't like having the number be part of the name, but you asked for it.
      named_scope :with_one_bar, :joins => :bars, :group => "bars.foo_id", :having => "count(bars.foo_id) = 1"
    
      # More generically...
      named_scope :with_n_bars, lambda {|n| {:joins => :bars, :group => "bars.foo_id", :having => ["count(bars.foo_id) = ?", n]}}
      named_scope :with_gt_n_bars, lambda {|n| {:joins => :bars, :group => "bars.foo_id", :having => ["count(bars.foo_id) > ?", n]}}
    
    end
    

    Called like so:

    Foo.with_n_bars(2)