class Person < ActiveRecord::Base
has_many :pets
scope :with_dog, join(:pets).where("pets.type = 'Dog'")
scope :without_pets ???????????????????????????????????
end
class Pet < ActiveRecord::Base
belongs_to :people
end
我想在Person模型中添加一个范围,以返回没有宠物的人。有任何想法吗?我觉得这很明显,但此刻它正在逃避我。
答案 0 :(得分:22)
scope :without_pets, lambda { includes(:pets).where('pets.id' => nil) }
答案 1 :(得分:9)
尝试这样的事情:
Person.joins('left outer join pets on persons.id=pets.person_id').
select('persons.*,pets.id').
where('pets.id is null')
我没有测试过,但它应该可以工作。
我们的想法是我们正在执行左外连接,因此对于没有宠物的每个人来说,宠物字段将为空。您可能需要在连接中包含:readonly => false
,因为当join()
传递一个字符串时,ActiveRecord会返回只读对象。
答案 2 :(得分:5)
这里写的是范围:
scope :without_pets, joins("left outer join pets on pets.person_id = persons.id").where("pets.id is null")
(如果这不起作用,尝试用'人'代替'人' - 我不确定你的桌名是什么。)
答案 3 :(得分:1)
您必须使用LEFT OUTER JOIN才能查找没有相关记录的记录。这是我使用的代码的改编版本:
scope :without_pets, joins('LEFT OUTER JOIN pets ON people.id = pets.person_id').group('people.id').having('count(pets.id) = 0')
答案 4 :(得分:0)
我不确定你的宠物模型是否有人ID,但也许这种尝试会以某种方式帮助你
scope :with_dog, joins(:pets).where("pets.type = 'Dog'")
scope :without_pets, joins(:pets).where("pets.person_id != persons.id")
更新:将查询方法名称从“加入”更正为“加入”。