gpt4 book ai didi

ruby-on-rails - 使用 ActiveRecord 助手删除 VS 查找孤儿

转载 作者:行者123 更新时间:2023-11-29 11:47:29 25 4
gpt4 key购买 nike

我正在尝试删除所有不再有任何用户组织

使用下面的代码,我可以找到我想删除的所有记录:

Organization.includes(:users)
.where(users: { id: nil })
.references(:users)

当我添加 delete_all 时,我得到了与不包含 references 时相同的错误:

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "users"

我可能可以用纯 SQL 编写解决方案,但我不明白为什么在我添加 delete_all 语句时 Rails 没有保留对 users 的引用。

这里有更多的细节:

Organization:
has_many :users

User:
belongs_to :organization

最佳答案

我发现 includes 仅对预加载有用(而且它很少处理我的情况),并且在与 references 结合使用时它生成一些完全疯狂的东西(用类似tN_rM 的东西给每个字段加上别名)即使它实际上做了一个LEFT OUTER JOIN...哪个<如果delete_all 出现后它没有消失,em>可能会有所帮助!

我发现使用 exists 会更清晰、更简单。它是 Arel(避免它是没有意义的,无论如何它都在 ActiveRecord 的引擎盖下),但它是一个很小的部分,几乎不会引起注意:

Organization.where(
User.where('users.organization_id = organizations.id').exists.not
)

或者,如果您觉得这串 SQL 不好看,请多使用一点 Arel,这样它就会变得引人注目:

Organization.where(
User.where(organization_id: Organization.arel_table[:id]).exists.not
) # I tend to extract these ^^^^^^^^^^^^^^^^^^^^^^^ into local variables

这处理链接 .delete_all 在顶部就好了,因为它不是(语法上)连接,即使它实际上等同于一个连接。

这背后的魔力

SQL 有一个 EXISTS 运算符,它在功能上类似于连接,只是不能从连接表中选择字段。它形成一个有效的 bool 表达式,可以取反放入WHERE条件

在“无 SQL”形式中,我使用了一个表达式“表的列”,结果证明它可用于 Rails 的散列条件。这是一个偶然的发现,是 Arel 为数不多的不会使代码过于庞大的用途之一。

关于ruby-on-rails - 使用 ActiveRecord 助手删除 VS 查找孤儿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33180042/

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