gpt4 book ai didi

ruby-on-rails - 想要查找 Rails 中没有关联记录的记录

转载 作者:行者123 更新时间:2023-12-03 04:16:40 27 4
gpt4 key购买 nike

考虑一个简单的关联...

class Person
has_many :friends
end

class Friend
belongs_to :person
end

让所有在 ARel 和/或 meta_where 中没有 friend 的人最干净的方法是什么?

然后 has_many :through 版本怎么样

class Person
has_many :contacts
has_many :friends, :through => :contacts, :uniq => true
end

class Friend
has_many :contacts
has_many :people, :through => :contacts, :uniq => true
end

class Contact
belongs_to :friend
belongs_to :person
end

我真的不想使用 counter_cache - 从我读到的内容来看,它不适用于 has_many :through

我不想提取所有 person.friends 记录并在 Ruby 中循环它们 - 我想要一个可以与 meta_search gem 一起使用的查询/范围

我不介意查询的性能成本

距离实际 SQL 越远越好...

最佳答案

更新 4 - Rails 6.1

感谢Tim Park指出在即将推出的 6.1 中您可以执行以下操作:

Person.where.missing(:contacts)

感谢the post他也链接到。

更新 3 - Rails 5

感谢 @Anson 提供的出色的 Rails 5 解决方案(为他下面的回答给他一些 +1),您可以使用 left_outer_joins 来避免加载关联:

Person.left_outer_joins(:contacts).where(contacts: { id: nil })

我将其包含在此处,以便人们可以找到它,但他应该为此获得+1。很棒的补充!

更新2

有人问逆,没有人的 friend 。正如我在下面评论的那样,这实际上让我意识到最后一个字段(上面::person_id)实际上不必与您返回的模型相关,它只需是一个连接表中的字段。它们都将是nil,所以它可以是其中的任何一个。这导致了上述问题的更简单的解决方案:

Person.includes(:contacts).where(contacts: { id: nil })

然后切换它以返回没有人的 friend 变得更简单,你只改变前面的类:

Friend.includes(:contacts).where(contacts: { id: nil })

更新

在评论中有一个关于 has_one 的问题,所以只是更新。这里的技巧是 includes() 需要关联的名称,而 where 需要表的名称。对于 has_one ,关联通常以单数表示,因此会发生变化,但 where() 部分保持原样。因此,如果一个 Person 只有 has_one :contact 那么你的语句将是:

Person.includes(:contact).where(contacts: { person_id: nil })

原版

更好:

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

对于 hmt 来说,基本上是一样的,你依赖的事实是,一个没有 friend 的人也没有联系人:

Person.includes(:contacts).where(contacts: { person_id: nil })

关于ruby-on-rails - 想要查找 Rails 中没有关联记录的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5319400/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com