ActiveRecord查询以识别孤立子记录

San*_*ngh 5 activerecord query-string ruby-on-rails-4 postgresql-9.3

我有邮政和用户模型。每个帖子都属于一个用户。但是,在数据库导入期间,在某些帖子中输入了一些错误的user_id。查询将获得其user_ids不引用任何用户的帖子的查询是什么?谢谢。

amo*_*ebe 9

如@ user2553863所述,Rails 5添加了对的支持left_outer_joins,这意味着您现在可以高效地执行此操作,而无需编写任何类似以下的SQL:

Post.left_outer_joins(:user).where(users: {id: nil}).delete_all
Run Code Online (Sandbox Code Playgroud)

这将查找任何孤立的帖子(没有用户的帖子)并将其删除。在这里,user是关联名称,users也是联接表的名称。您无需额外触发SELECT即可查询所有用户ID,当您有许多用户时,这可能会中断。


Jon*_*ton 7

轨道 6.1+

您可以使用“missing”方法来获取孤立记录。例如

Class User
end

Class Post
  belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)

这是使用缺失方法时的情况

Post.where.missing(:user)
Run Code Online (Sandbox Code Playgroud)

这将获取所有具有 user_id 但相应用户被删除的 Post 记录。


use*_*863 6

桑杰,

提出的所有解决方案都适用于小型表,但根据所涉及的表的大小以及可用的内存量和处理能力,出于性能原因,您可能需要使用 LEFT OUTER JOIN,如下所示:

Post.joins("LEFT OUTER JOIN users ON posts.user_id = user.id")
    .where("user.id IS NULL")
Run Code Online (Sandbox Code Playgroud)

在 Rails 5 中,ActiveRecord 支持 LEFT OUTER JOIN

问候


Man*_*ijn 4

我会执行以下操作,这将产生一个SELECT和一个DELETE语句(因此总共 2 个查询)

Post.where('`posts`.`user_id` NOT IN (?)', User.pluck(:id)).delete_all
Run Code Online (Sandbox Code Playgroud)