我的问题与此问题非常相似:Want to find records with no associated records in Rails 3
但有一点扭曲。让我们使用他们的示例并添加我的问题:
class Person
has_many :friends
end
class Friend
belongs_to :person
attr_accessor :type # this can be 'best' or 'acquaintance'
end
我希望所有人都没有“最好的”#39;朋友。我看到的大多数情况下的正常查询是让没有朋友的人。那将是:
Person.includes(:friends).where( :friends => { :person_id => nil } )
但那不是我想要的。有没有办法让所有没有“最好”的人得到#39;朋友不管他们有多少其他类型的朋友?
答案 0 :(得分:2)
如果您使用支持对查询否定的rails 4.2,您可以执行以下操作:
self.model
在任何其他情况下:
Person.includes(:friends).where.not( friends: { type: "best" } )
<强>更新强>
可能有点偏离主题,但您可以考虑在活动记录中使用enum,以便映射这些内容,例如:
Person.includes(:friends).where("friends.type != 'best'")
然后你可以像这样查询:
class Friend
belongs_to :person
enum type: {best: 0, acquaintance: 1}
end
这使得它更具可读性和红宝石友好性并避免使用字符串,因为该值在db中存储为整数。
答案 1 :(得分:0)
使用NOT EXISTS
子查询时,最直接的,但不是唯一的,也不一定是最高效的方法:
Person.where('NOT EXISTS(SELECT 1 FROM friends WHERE person_id=persons.id AND type=?)', 'best')
您可以将其定义为Person
上的范围,以便于合成。
注意:我还想指出,虽然古斯塔沃的解决方案读起来就像你期望的那样,它会让任何有朋友不是他们最好朋友的人回归(不只是没有任何好朋友的人)。这是由于SQL的where子句如何在每行的基础上运行,并且无法在组或一对多关系上断言。