delete_all vs destroy_all? - PullRequest
       1

delete_all vs destroy_all?

179 голосов
/ 14 июля 2011

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

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
u.sources.destroy_all
u.user_stats.destroy_all
u.delete

Это работает и удаляет все ссылки пользователя из всех таблиц, но я слышал, что destroy_all был очень тяжелым процессомпоэтому я попробовал delete_all.Он только удаляет пользователя из его собственной пользовательской таблицы, а id из всех других таблиц обнуляется, но оставляет записи в них нетронутыми.Может кто-нибудь поделиться тем, что правильно для выполнения такой задачи?

Я вижу, что destroy_all вызывает функцию destroy для всех связанных объектов, но я просто хочу подтвердить правильный подход.

Ответы [ 4 ]

222 голосов
/ 14 июля 2011

Вы правы. Если вы хотите удалить пользователя и все связанные объекты -> destroy_all Однако, если вы просто хотите удалить пользователя, не подавляя все связанные объекты -> delete_all

Согласно этому сообщению: Рельсы: зависимые =>: уничтожить VS: зависимые =>: delete_all

  • destroy / destroy_all: связанные объекты уничтожаются вместе с этим объектом путем вызова их метода уничтожения
  • delete / delete_all: Все связанные объекты уничтожаются немедленно, без вызова их: destroy метод
21 голосов
/ 15 июля 2011

delete_all - это один оператор SQL DELETE и ничего более.destroy_all вызывает destroy () для всех совпадающих результатов: условий (если они у вас есть), которые могут быть как минимум NUM_OF_RESULTS SQL-операторами.

Если вам нужно сделать что-то радикальное, например destroy_all () для большого набора данных, я бы, вероятно, не сделал бы это из приложения и не стал бы обрабатывать это вручную с осторожностью.Если набор данных достаточно мал, вам не будет так больно.

16 голосов
/ 14 февраля 2013

Чтобы избежать того факта, что destroy_all создает все записи и уничтожает их по одной, вы можете использовать их непосредственно из класса модели.

Так что вместо:

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all

Вы можете сделать:

u = User.find_by_name('JohnBoy')
UsageIndex.destroy_all "user_id = #{u.id}"

В результате один запрос уничтожает все связанные записи

1 голос
/ 11 января 2017

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

Этот драгоценный камень добавляет новую опцию для ассоциаций ActiveRecord:

в зависимости:: delete_recursively

Когда вы уничтожаете запись, все записи, связанные с этим параметром, будут рекурсивно удаляться (то есть в разных моделях) без создания какой-либо из них.

Обратите внимание, что, так же, как зависимый:: удалить или зависимый:: delete_all, эта новая опция не запускает обратные вызовы вокруг / до / после_дестрой зависимых записей.

Однако возможно иметь::: уничтожать ассоциации в любом месте в цепочке моделей, которые иначе связаны с:: delete_recursively. Опция: destroy обычно будет работать в любом месте вверх или вниз, создавая экземпляры и уничтожая все соответствующие записи и, таким образом, вызывая их обратные вызовы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...