查找rails 3中没有关联记录的记录

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模型中添加一个范围,以返回没有宠物的人。 有任何想法吗? 我觉得这很明显,但此刻它正在逃避我。

尝试这样的事情:

 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会返回只读对象。

 scope :without_pets, lambda { includes(:pets).where('pets.id' => nil) } 

Mark Westling的回答是正确的。 外连接是正确的方法。 内部联接(如果您传递联接的名称/符号而不是您自己的SQL,则联接方法生成的内容)将不起作用,因为它不包括没有宠物的人。

这里写的是一个范围:

 scope :without_pets, joins("left outer join pets on pets.person_id = persons.id").where("pets.id is null") 

(如果这不起作用,尝试用’人’替换’人’ – 我不确定你的表名是什么。)

您必须使用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') 

我不确定你的宠物模型是否有人ID,但也许这种尝试可以帮助你

 scope :with_dog, joins(:pets).where("pets.type = 'Dog'") scope :without_pets, joins(:pets).where("pets.person_id != persons.id") 

更新:将查询方法名称从“加入”更正为“加入”。