Почему ActiveRecord предоставляет .delete_all, а не .truncate? - PullRequest
10 голосов
/ 15 октября 2011

Кажется странным, что я должен вручную выполнить SQL, чтобы использовать команду TRUNCATE.Есть ли что-то плохое в этом, от чего DHH защищает меня?

Ответы [ 4 ]

10 голосов
/ 15 октября 2011

Использование TRUNCATE в некоторых базах данных не запускает триггеры. Использование DELETE для каждой строки все равно будет запускать триггеры. TRUNCATE также нельзя откатить, поэтому, если вы сделали .destroy_all в транзакции, она сотрет все данные, даже если вы попытались выполнить откат.

Итак, да, вы защищены от воздействия усечения.

3 голосов
/ 22 декабря 2015

Если вы используете MySQL или Postgre, а не SQlite3 (который не поддерживает TRUNCATE), вы можете добавить в вашу модель следующий метод.

def self.truncate
  self.connection_pool.with_connection { |c| c.truncate(table_name) }
end

Обратите внимание, что это не будет вызывать обратные вызовы ActiveRecord. Есть лучшие способы сделать это, которые не привязывают ваш код к конкретной реализации БД, но даже это лучше, чем писать SQL самостоятельно.

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

Существует множество вариантов использования для TRUNCATE, и, на мой взгляд, приведенных здесь ответов очень недостаточно. Используя Postgres в качестве примера:

  • TRUNCATE определенно безопасен для транзакций в некоторых СУБД, как уже отмечалось jsears. Это можно откатить, по крайней мере, в Postgres. Разве Rails не должен быть db-независимым и позволять такие вещи?
  • TRUNCATE также выполнит триггеры BEFORE TRUNCATE или AFTER TRUNCATE в Postgres. Если вы ожидаете, что триггер DELETE сработает на TRUNCATE, это ваша ошибка проектирования!
  • TRUNCATE работает намного быстрее, чем DELETE, особенно для больших наборов данных, потому что это один короткий оператор DDL.
  • В архитектуре Postgres MVCC TRUNCATE удаляет все индексы и таблицы.

По этим причинам для меня безумие, что Rails не поддерживает TRUNCATE. Нет, я не думаю, что приведенные причины являются хорошими.

0 голосов
/ 15 октября 2011

Взгляните на Model.destroy_all и активную запись: зависимые =>: уничтожить отношения.Если вы не укажете: variable =>: destory, некоторые из значений по умолчанию - установить отношение к null, но не уничтожить запись.

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