我有一个与has_many
关系的模型与另一个模型如此:
class Parent < ActiveRecord::Base
has_many :children
end
class Child < ActiveRecord::Base
belongs_to :parent
end
由于有些父母可能没有孩子,我想做一个只返回有孩子的父母的查询。我怎么会这样做?
由于我在Rails 3上执行此操作,如果此查询不使用where.not.
语法,将会很有帮助。
答案 0 :(得分:12)
Parent.includes(:children).where.not(children: {id: nil})
或
Parent.joins(:children).where.not(children: {id: nil}).distinct
Parent.joins(:children).where('children.id NOT NULL').distinct
答案 1 :(得分:2)
可以使用SQL语法
完成Parent.where('id IN (SELECT DISTINCT(parent_id) FROM children')
或者,为了保持DRY,可以在范围内使用:
class Parent < ActiveRecord::Base
has_many :children
scope :with_children, where('id IN (SELECT DISTINCT(parent_id) FROM children')
end
然后你可以找到有孩子的父母:
Parent.with_children
答案 2 :(得分:0)
Rails 7 引入了一种检查关联是否存在的新方法 - where.associated。
请看下面的代码片段:
# Before:
account.users.joins(:contact).where.not(contact_id: nil)
# After:
account.users.where.associated(:contact)
这是一个在后台使用的 SQL 查询示例:
Post.where.associated(:author)
# SELECT "posts".* FROM "posts"
# INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
# WHERE "authors"."id" IS NOT NULL
因此,您的特定案例可以改写如下:
Parent.where.associated(:child)
谢谢。
来源:
注意事项:
答案 3 :(得分:-2)
类似于Wes&#39;回答,但保持有点害羞的SQL语法:
Parent.find(Child.all.map{|c|c.parent_id}.uniq)
这一位:
Child.all.map{|c|c.parent_id}.uniq
为您提供了一个parent_id数组(使用.uniq
删除了dupes)。
从那里,它是一个简单的.find
。或者,如果您愿意,请使用.where
。