Найти все объекты с нарушенной ассоциацией - PullRequest
7 голосов
/ 04 ноября 2010

У меня есть две модели в моем приложении rails с множеством и принадлежит ассоциации.В категории есть много элементов, а элемент принадлежит категории.

Эти модели связаны обычным образом через столбец category_id в модели элемента.

Я ищу быстрый способ найти всеэлементы в базе данных с нарушенными ассоциациями.т.е. найти все категории, которые существуют без связанных элементов, и элементы, которые существуют без связанной категории.

Например, если у меня есть элемент с category_id 7, но категория с идентификатором 7 была удалена, то этобудет считаться сломанным.

Ответы [ 2 ]

7 голосов
/ 21 января 2015

Для вашего примера, чтобы найти элементы с category_id для категорий, которые больше не существуют:

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

Возможно, вы захотите посмотреть и на это: Задача rake для отслеживания отсутствующих индексов базы данных (хотя не внешних ключей, а индексов): https://github.com/eladmeidar/rails_indexes

1 голос
/ 04 ноября 2010

Очень эффективный способ - использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...