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

时间:2011-03-16 21:34:12

标签: ruby-on-rails scope

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

5 个答案:

答案 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)

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

这里写的是范围:

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")

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