【问题标题】:Find all record without association with a certain field查找与某个字段没有关联的所有记录
【发布时间】:2016-08-30 11:23:24
【问题描述】:

我的问题和这个问题很相似: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

我想让所有人都没有“最好的”朋友。我看到的大多数情况下的正常查询是让没有任何朋友的人。那将是:

Person.includes(:friends).where( :friends => { :person_id => nil } )

但这不是我想要的。有没有办法让所有没有“最好”朋友的人不管他们有多少其他类型的朋友?

【问题讨论】:

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


    【解决方案1】:

    如果您使用的是支持否定查询的 rails 4.2,您可以执行以下操作:

    Person.includes(:friends).where.not( friends: { type: "best" } )
    

    在任何其他情况下:

    Person.includes(:friends).where("friends.type != 'best'")
    

    更新

    可能有点离题,但您可以考虑使用活动记录中的enum,以便映射此类内容,例如:

    class Friend
       belongs_to :person
       enum type: {best: 0, acquaintance: 1}
    end
    

    那么你可以这样查询:

    Person.includes(:friends).where.not( friends: { type: Friend.types[:best] } )
    

    这使得它更具可读性、对 ruby​​ 友好并且避免使用字符串,因为该值以整数形式存储在数据库中。

    【讨论】:

      【解决方案2】:

      最直接的方法是使用NOT EXISTS 子查询:

      Person.where('NOT EXISTS(SELECT 1 FROM friends WHERE person_id=persons.id AND type=?)', 'best')
      

      您可以将其定义为Person 上的范围,以便于组合。

      注意:我还想指出,虽然 Gustavo 的解决方案看起来像您期望的那样,但它会返回任何有朋友但不是他们最好朋友的人(不仅仅是没有任何最好朋友的人)。这是由于 SQL 的 where 子句如何在每行基础上运行,并且难以断言组或一对多关系。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-23
        • 1970-01-01
        • 2014-12-08
        • 2023-03-20
        相关资源
        最近更新 更多