Видалення всіх записів у таблиці бази даних


Відповіді:


249

Якщо ви шукаєте шлях до нього без SQL, ви повинні мати можливість delete_all.

Post.delete_all

або з критеріями

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

Дивіться тут для отримання додаткової інформації.

Записи видаляються, не завантажуючи їх спочатку, що робить це дуже швидко, але порушує функціональність, як кеш-лічильник, який залежить від коду рейлів, який буде виконуватися після видалення.


13
Варто зауважити, що якщо у вас є асоціації з: залежною =>: знищити або що-небудь, що потрібно очистити після видалення, ви, ймовірно, захочете Post.destroy_all - хоча це набагато повільніше. Дивіться apidock.com/rails/ActiveRecord/Base/destroy_all/class
Michael Hellein

Ця відповідь передбачає, що в таблиці є пов'язана з нею модель. ОП не вказала цього - що робити, якщо таблиця є таблицею з'єднання?
Toby 1 Kenobi

1
@BradWerth, вважає він чи ні хорошим чи поганим стилем, я просто кажу, що цілком можливо, що у Rails db є таблиці, які не є ActiveRecordмоделями. Питання задає питання про видалення запису з "таблиці", і я просто вказую на припущення, яке міститься у відповіді.
Toby 1 Kenobi

У мене той самий запит, що і в @ Toby1Kenobi 's.
nbsamar

30

Видалити через SQL

Item.delete_all # accepts optional conditions

Видалити за допомогою виклику методу знищення кожної моделі (дорогий, але забезпечує зворотний виклик)

Item.destroy_all # accepts optional conditions

Усі тут


21

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

rake db:purge

Ви також можете це зробити в тестовій базі даних

rake db:test:purge

5

Якщо ви маєте на увазі видалити кожен екземпляр усіх моделей, я б використав

ActiveRecord::Base.connection.tables.map(&:classify)
  .map{|name| name.constantize if Object.const_defined?(name)}
  .compact.each(&:delete_all)

1
Віддайте перевагу selectбудь-коли, коли вам потрібно використовувати вираз if всередині блоку, таким чином вам не доведеться ланцюжок компактного методу для видалення нульових елементів.
Себастьян Пальма

4
BlogPost.find_each(&:destroy)

Це чудово підходить для обставин з низькою пам'яттю.
Епіген

Це єдина відповідь, яка враховує споживання пам’яті.
Джон

2
Омг, навіщо робити цикл для цього ... сенсу немає. просто видаліть усі записи ВИДАЛИТИ З таблиці, Model.delete_all
Imnl

@John, чому один-єдиний запит витрачає більше пам’яті, ніж цикл запитів?
Imnl

@Imnl Кожна ітерація створює новий екземпляр розглянутої моделі, щоб вона могла обробляти зворотні виклики методу видалення.
Джон

2

Якщо ваша модель називається BlogPost, це буде:

BlogPost.all.map(&:destroy)

це отримає кожен BlogPost і завантажить його в масив Ruby, перш ніж знищити їх.
hdgarrood

Залежить від ORM. Datamapper не зробив би цього, оскільки ви нічого не вимагаєте про кожну модель. А ось монгоїдна стежка, яка показує, що вона не вибирає жодних полів перед тим, як знищувати кожен запис: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на всіх моделях.

Зауважте, що ми не перечищаємо таблицю міграції SchemaMigra.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.