Usunięcie wszystkich rekordów w tabeli bazy danych


Odpowiedzi:


253

Jeśli szukasz sposobu na to bez SQL, powinieneś być w stanie użyć delete_all.

Post.delete_all

lub z kryteriami

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

Więcej informacji znajdziesz tutaj .

Rekordy są usuwane bez ich wcześniejszego ładowania, co czyni je bardzo szybkimi, ale psuje funkcjonalność, taką jak pamięć podręczna liczników, która zależy od kodu szyn, który ma być wykonany po usunięciu.


13
Warto zauważyć, że jeśli masz skojarzenia z: depend =>: niszcz lub czymkolwiek, co musi zostać wyczyszczone po usunięciu, prawdopodobnie będziesz chciał Post.destroy_all - chociaż jest znacznie wolniejszy. Zobacz apidock.com/rails/ActiveRecord/Base/destroy_all/class
Michael

Ta odpowiedź zakłada, że ​​tabela ma skojarzony z nią model. OP nie określił tego - co jeśli tabela jest stołem łączenia?
Toby 1 Kenobi

1
@BradWerth, niezależnie od tego, czy niektórzy uważają to za dobry lub zły styl, mówię tylko, że jest możliwe, aby baza danych Railsów zawierała tabele, które nie są ActiveRecordmodelami. Pytanie dotyczy usunięcia rekordu z „tabeli”, a ja tylko wskazuję lub założenie zawarte w odpowiedzi.
Toby 1 Kenobi

Mam takie samo zapytanie jak @ Toby1Kenobi.
nbsamar

30

Aby usunąć przez SQL

Item.delete_all # accepts optional conditions

Aby usunąć, wywołując metodę zniszczenia każdego modelu (kosztowna, ale zapewnia wywołanie zwrotne)

Item.destroy_all # accepts optional conditions

Wszystko tutaj


23

jeśli chcesz całkowicie opróżnić bazę danych, a nie tylko usunąć model lub modele do niej dołączone, możesz:

rake db:purge

możesz to również zrobić w testowej bazie danych

rake db:test:purge

6

Jeśli masz na myśli usunięcie każdej instancji wszystkich modeli, użyłbym

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

1
Preferuj, selectgdy potrzebujesz użyć wyrażenia if wewnątrz bloku, w ten sposób unikniesz konieczności łączenia w łańcuch metody kompaktowej w celu usunięcia elementów zerowych.
Sebastian Palma,

4
BlogPost.find_each(&:destroy)

1
Jest to świetne rozwiązanie w przypadku małej ilości pamięci.
Epigene,

To jedyna odpowiedź, która bierze pod uwagę zużycie pamięci.
John

2
O mój Boże, po co robić pętlę ... bez sensu. po prostu usuń wszystkie rekordy DELETE FROM table, Model.delete_all
Imnl

@John, dlaczego jedno zapytanie zużywa więcej pamięci niż pętla zapytań?
Imnl

@Imnl Każda iteracja tworzy nową instancję danego modelu, aby mógł on przetwarzać wywołania zwrotne metody delete.
John

2

Jeśli Twój model nazywa się BlogPost, wyglądałoby to tak:

BlogPost.all.map(&:destroy)

to pobierze każdy pojedynczy BlogPost i załaduje go do tablicy Ruby przed ich zniszczeniem.
hdgarrood

Zależy od ORM. Datamapper nie zrobiłby tego, ponieważ nie żądasz niczego na temat każdego modelu. A oto ślad stosu Mongoida, który pokazuje, że nie wybiera żadnych pól przed zniszczeniem każdego wpisu: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
ponieważ jest to kwestia szyny, a pytający nie powiedział który ORM on używa, powinniśmy zakładać ActiveRecord
hdgarrood

2

Nowsza odpowiedź w przypadku, gdy chcesz usunąć wszystkie wpisy we wszystkich tabelach:

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

Więcej informacji na temat eager_load tutaj .

Po jej wywołaniu możemy uzyskać dostęp do wszystkich potomków ActiveRecord::Basei możemy zastosować a delete_allna wszystkich modelach.

Pamiętaj, że nie usuwamy tabeli SchemaMigration.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.