查找所有关联断开的对象

Posted

技术标签:

【中文标题】查找所有关联断开的对象【英文标题】:Find all objects with broken association 【发布时间】:2010-11-03 23:01:31 【问题描述】:

我的 rails 应用程序中有两个模型,其中一个有很多,并且属于关联。 Category有很多item,Item属于category。

这些模型通过 Item 模型中的 category_id 列以正常方式关联。

我正在寻找一种快速查找数据库中关联断开的所有元素的方法。 即查找所有不存在关联项目的类别和不存在关联类别的项目。

例如,如果我有一个 category_id 为 7 的项目,但 id 为 7 的类别已被删除,那么这将被视为损坏。

【问题讨论】:

这里有一个更新的 Rails 3 变体和近乎欺骗:***.com/questions/9471395/… 【参考方案1】:

对于您的示例,查找具有 category_id 的项目以用于不再存在的类别:

Item.where('NOT EXISTS (SELECT * FROM categories where category.id = item.category_id)')

您可能还想看看这个: 追踪丢失的数据库索引(不是外键,而是索引)的 rake 任务:https://github.com/eladmeidar/rails_indexes

【讨论】:

【参考方案2】:

一个非常有效的方法是使用find_by_sql 让数据库完成繁重的工作:

uncategorized_items = Item.find_by_sql("select * from items where category_id IS NULL")

另一种方式是命名作用域:

class Item < ActiveRecord::Base
  scope :uncategorized, where(:category_id => nil) # rails 3

  # or...

  named_scope :uncategorized, :conditions => 'category_id IS NULL'
end

这些只是一些想法。我假设一旦你发现了这些损坏的关联,你就打算修复它们,对吧?如果对您来说重要的是不要再次发生这种情况,您可能希望在两个模型中都使用validates_associated

您可以使用 find_by_sql 和左外连接来查找一个表中的所有项目,但不能查找另一个表中的所有项目。在这里,我使用了一个下载表和一个 image_files 表(我只包含了 SQL):

SELECT d.*, d.image_file_id
from downloads as d
LEFT OUTER JOIN image_files as i 
ON i.id = d.image_file_id 
WHERE d.image_file_id IS NULL

【讨论】:

那只会找到 category_id 为空的对象。我正在寻找的是一种查找其 category_id 已填充但相关对象不存在的对象的方法。例如,如果 category_id 为 7,但 id 为 7 的关联类别不再存在。 find_by_sql 和左外连接是你的朋友。这是一个使用下载和 image_files 表的示例(编辑后的原始答案)。

以上是关于查找所有关联断开的对象的主要内容,如果未能解决你的问题,请参考以下文章

ActiveRecord 查找所有有关联孩子的父母

查找关联计数大于零的所有记录

Sequelize 基于关联的查找

Greenplum:查找任何外部表的关联错误表

CakePHP 2.1 - 模型关联 - 保存和查找

查找断开的符号链接