Я видел этот вопрос несколько раз, но все ответы основаны на небольших наборах данных или ограниченных ассоциациях, так что здесь снова.
У меня есть отношение has_many_through
class ModelA
has_many :model_c, :through => :model_b
has_many :model_b
class ModelB
belongs_to :model_a
belongs_to :model_b
class ModelC
has_many :model_a, :through => :model_b
has_many :model_b
Мне нужно очистить «осиротевшие» модели B и модели C, в которых модель A была удалена. Поэтому мне нужно найти и удалить модель B без модели A, а затем модель C без модели B.
Мы не делали этого при удалении модели А, потому что одна модель А может быть связана с десятками тысяч моделей С, и это занимало слишком много времени - наше использование зависимого уничтожения с защитным блоком, запущенным слишком много запросов и заняли слишком много времени. Вместо этого мы планируем выполнять уборку по ночам.
Итак, мне нужно найти и удалить все ModelB, чьи столбцы model_a содержат идентификатор для несуществующей модели A, и удалить их.
Решения, которые я нашел до сих пор, которые не будут работать для меня (потому что у нас могут быть сотни тысяч сирот в данный момент времени):
- загрузка всех идентификаторов из ModelA.id и ModelB.model_a и выполнение разницы в наборах
- загрузка всех идентификаторов из ModelA.id и передача запроса «NOT IN» в Model B
- проверка по модели C запись за записью
На данный момент, я думаю, мне нужно прямое решение SQL (с которым я в порядке), но я не совсем уверен, что я ищу.
(БД - MySQL)