找到没有与某个字段关联的所有记录

时间:2016-05-04 20:40:52

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord rails-activerecord

我的问题与此问题非常相似: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;朋友不管他们有多少其他类型的朋友?

2 个答案:

答案 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子句如何在每行的基础上运行,并且无法在组或一对多关系上断言。