Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
617 views
in Technique[技术] by (71.8m points)

ruby on rails - ActiveRecord find all parents that have associated children

I don't know why I can't figure this out, I think it should be fairly simple. I have two models (see below). I'm trying to come up with a named scope for SupplierCategory that would find all SupplierCategory(s) (including :suppliers) who's associated Supplier(s) are not empty.

I tried a straight up join, named_scope :with_suppliers, :joins => :suppliers which gives me only categories with suppliers, but it gives me each category listed separately, so if a category has 2 suppliers, i get the category twice in the returned array:

Currently I'm using:

named_scope :with_suppliers, :include => :suppliers

and then in my view I'm using:

<%= render :partial => 'category', :collection => @categories.find_all{|c| !c.suppliers.empty? } %>

Not exactly eloquent but illustrates what I'm trying to achieve.

Class Definitions

class SupplierCategory < AR
  has_many :suppliers, :order => "name"
end

class Supplier < AR
  belongs_to :supplier
end
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here is one more approach:

named_scope :with_suppliers, :include    => :suppliers, 
                             :conditions => "suppliers.id IS NOT NULL"

This works because Rails uses OUTER JOIN for include clause. When no matching rows are found the query returns NULL values for supplier columns. Hence NOT NULL check returns the matching rows.

Rails 4

scope :with_suppliers, { includes(:steps).where("steps.id IS NOT NULL") }

Or using a static method:

def self.with_suppliers
  includes(:steps).where("steps.id IS NOT NULL")
end

Note:

This solution eager loads suppliers.

categories = SupplierCategory.with_suppliers
categories.first.suppliers #loaded from memory

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...