Удаление всех записей в таблице базы данных

Ответы:

249

Если вы ищете способ обойтись без SQL, вы можете использовать delete_all.

Post.delete_all

или с критериями

Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')"

См. Здесь для получения дополнительной информации.

Записи удаляются без предварительной загрузки, что делает это очень быстро, но нарушает такие функции, как кеш счетчика, который зависит от кода rails, который будет выполняться при удалении.

HakonB
источник
13
Стоит отметить, что если у вас есть ассоциации с: зависимым =>: destroy или чем-либо, что нужно очистить после удаления, вам, вероятно, понадобится Post.destroy_all, хотя он намного медленнее. См. Apidock.com/rails/ActiveRecord/Base/destroy_all/class
Майкл Хеллейн
Этот ответ предполагает, что с таблицей связана модель. OP не указал этого - что, если таблица является таблицей соединения?
Тоби 1 Кеноби
1
@BradWerth, независимо от того, считается ли это хорошим или плохим стилем, я просто говорю, что возможно, что в базе данных Rails есть таблицы, которые не являются ActiveRecordмоделями. Вопрос касается удаления записи из «таблицы», и я просто указываю на предположение, содержащееся в ответе.
Тоби 1 Кеноби
У меня такой же запрос, что и у @ Toby1Kenobi.
nbsamar
30

Удалить через SQL

Item.delete_all # accepts optional conditions

Для удаления путем вызова метода уничтожения каждой модели (дорого, но гарантирует вызов обратных вызовов)

Item.destroy_all # accepts optional conditions

Все здесь

lebreeze
источник
21

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

rake db:purge

вы также можете сделать это в тестовой базе данных

rake db:test:purge
KensoDev
источник
5

Если вы имеете в виду удалить все экземпляры всех моделей, я бы использовал

ActiveRecord::Base.connection.tables.map(&:classify)
  .map{|name| name.constantize if Object.const_defined?(name)}
  .compact.each(&:delete_all)
dfaulken
источник
1
Предпочитайте selectвсякий раз, когда вам нужно использовать выражение if внутри блока, так вам не придется связывать компактный метод для удаления элементов nil.
Себастьян Пальма
4
BlogPost.find_each(&:destroy)
Филипп
источник
Это отлично подходит для случаев нехватки памяти.
Epigene
Это единственный ответ, учитывающий потребление памяти.
Джон
2
Омг, зачем делать петлю для этого ... смысла нет. просто удалите все записи УДАЛИТЬ ИЗ таблицы, Model.delete_all
Imnl
@John, почему один-единственный запрос потребляет больше памяти, чем цикл запросов?
Imnl
@Imnl Каждая итерация создает новый экземпляр рассматриваемой модели, чтобы он мог обрабатывать обратные вызовы для метода удаления.
Джон
2

Если ваша модель называется BlogPost, это будет:

BlogPost.all.map(&:destroy)
Stef
источник
это получит каждый BlogPost и загрузит его в массив Ruby перед их уничтожением.
hdgarrood
Зависит от ORM. Datamapper этого не сделает, потому что вы ничего не запрашиваете по каждой модели. А вот трассировка стека Mongoid, показывающая, что не выбирает никаких полей перед уничтожением каждой записи:MOPED: 127.0.0.1:27017 QUERY database=a_database collection=nothings selector={} flags=[:slave_ok] limit=0 skip=0 batch_size=nil fields=nil (0.3378ms)
stef
4
так как это вопрос рельсов, и спрашивающий не сказал, какой ORM он использует, мы должны предположить ActiveRecord
hdgarrood
2

Более свежий ответ в случае, если вы хотите удалить все записи в каждой таблице:

def reset
    Rails.application.eager_load!
    ActiveRecord::Base.descendants.each { |c| c.delete_all unless c == ActiveRecord::SchemaMigration  }
end

Подробнее об этом eager_load здесь .

После его вызова мы можем получить доступ ко всем потомкам ActiveRecord::Baseи применить delete_allко всем моделям.

Обратите внимание, что мы не очищаем таблицу SchemaMigration.

Саймон Нинон
источник