Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 756
Joe Cairns Avatar asked Dec 03 '22 12:12

Joe Cairns


1 Answers

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)
like image 120
jdl Avatar answered Dec 25 '22 18:12

jdl