Jak usunąć wszystkie wiersze w tabeli za pomocą Eloquent?


145

Przypuszczałem, że użyję następującej składni:

MyModel::all()->delete();

Ale to nie zadziałało. Jestem pewien, że to super proste, ale szukałem dokumentacji na ten temat i nie mogę jej znaleźć!

Odpowiedzi:


296

Przyczyna MyModel::all()->delete()nie działa, ponieważ w all()rzeczywistości odpala zapytanie i zwraca kolekcję obiektów elokwentnych.

Możesz skorzystać z metody obcięcia, która działa dla Laravel 4 i 5:

MyModel::truncate();

Spowoduje to usunięcie wszystkich wierszy z tabeli bez rejestrowania usunięcia pojedynczych wierszy.


1
Dodałem rozwiązanie Laravel 3 do mojego pytania, dla przyszłych czytelników.
Pete

40
Ładny. Działa to również na Laravel 5, jeśli ktoś inny
szukałby

14
Uwaga: truncate () resetuje również każdy licznik AUTO_INCREMENT (pamiętaj również, że nie możesz obcinać tabel, które mają ograniczenia klucza obcego).
William Turrell

10
FYI: Turncate nie spowoduje usunięcia wydarzeń.
Fusion

1
Jeśli naprawdę chcesz skorzystać MyModel::all()->delete(), użyjforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl

75

Rozwiązanie Laravel 5.2+ .

Model::getQuery()->delete();

Po prostu weź bazowy kreator z nazwą tabeli i zrób cokolwiek. Nie może być bardziej uporządkowany.

Laravel 5,6 rozwiązanie

\App\Model::query()->delete();

9
Na wypadek, gdyby ktokolwiek był zdezorientowany, dlaczego to działa, klasa Model przekazuje metody do Builder za pośrednictwem magicznej metody __call tutaj . Ponieważ sama klasa modelu ma metodę delete, wywołanie Model :: delete () wywołuje metodę Model, gdy naprawdę potrzebujesz metody Builder. Aby jawnie pobrać kreator, możesz użyć metody getQuery ().
kevinAlbs,

To również nie usuwa powiązanych tabel, jeśli chcesz.
Terje Nesthus,


Model :: whereNotNull ('id') -> delete (); - wykona miękkie usuwanie, gdy miękkie usuwanie jest włączone
shalini

64

Możesz użyć, Model::truncate()jeśli wyłączysz foreign_key_checks(zakładam, że używasz MySQL).

DB::statement("SET foreign_key_checks=0");
Model::truncate();
DB::statement("SET foreign_key_checks=1");

2
W Laravel 4 używasz DB ::
unprepared

możesz także użyć Schema :: disableForeignKeyConstraints (); & Schemat :: enableForeignKeyConstraints ();
Eleazar Resendez

34

Widziałem obie metody używane w plikach seed.

// Uncomment the below to wipe the table clean before populating

DB::table('table_name')->truncate();

//or

DB::table('table_name')->delete();

Nawet jeśli nie możesz użyć pierwszego, jeśli chcesz ustawić klucze obce .

Nie można obciąć tabeli, do której odwołuje się ograniczenie klucza obcego

Więc dobrym pomysłem może być skorzystanie z drugiego.


2
deleteoczywiście to nie to samo, co truncatejednak.
Joel Mellon

2
@sudopeople Bardzo pomocne byłoby wskazanie różnicy. Mógłbym również dodać to do mojej odpowiedzi .
giannis christofakis

4
Nie można użyć TRUNCATE w transakcji, ponieważ ROLLBACK nie ma na nią wpływu. W takim przypadku można to osiągnąć za pomocą (new MyModel) -> newQuery () -> delete ().
hammurabi

12

Istnieje sposób pośredni:

myModel:where('anyColumnName', 'like', '%%')->delete();

Przykład:

User:where('id', 'like' '%%')->delete();

Informacje o narzędziu do tworzenia zapytań Laravel: https://laravel.com/docs/5.4/queries


1
@aschipfl właściwie niewiele do wyjaśnienia. Kod uruchamia SQL, DELETE FROM users WHERE id LIKE '%%'który dopasowuje wszystkie wiersze w tabeli, usuwając w ten sposób wszystko.
Hkan

To mnie wciągnęło. Skończyło się na tym, że wykonałem pluck () na innym modelu, aby uzyskać tablicę identyfikatorów, których potrzebowałem, a następnie użyłem tej tablicy do usunięcia wszystkich rekordów z mojego modelu za pomocą whereInmetody: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC

10

Chciałem dodać kolejną opcję dla tych, którzy dostają się do tego wątku przez Google. Musiałem to zrobić, ale chciałem zachować moją wartość automatycznego zwiększania, która jest truncate()resetowana. Nie chciałem też DB::niczego używać , ponieważ chciałem działać bezpośrednio na obiekcie modelu. Więc poszedłem z tym:

Model::whereNotNull('id')->delete();

Oczywiście kolumna będzie musiała faktycznie istnieć, ale w standardowym, nieszablonowym modelu elokwentnym idkolumna istnieje i nigdy nie jest pusta. Nie wiem, czy to najlepszy wybór, ale działa na moje potrzeby.


Model::delete();osiągnie to samo.
Leng

5
Niestety Model::delete()rzuca wyjątek Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, przynajmniej w Laravel 5.0.
Dave James Miller,

6

Nie mogłem użyć, Model::truncate()ponieważ spowodowałoby to błąd:

SQLSTATE [42000]: Błąd składni lub naruszenie zasad dostępu: 1701 Nie można obciąć tabeli, do której odwołuje się ograniczenie klucza obcego

I niestety Model::delete()nie działa (przynajmniej w Laravel 5.0):

Metoda niestatyczna Illuminate \ Database \ Eloquent \ Model :: delete () nie powinna być wywoływana statycznie, zakładając $ this z niezgodnego kontekstu

Ale to działa:

(new Model)->newQuery()->delete()

Spowoduje to nietrwałe usunięcie wszystkich wierszy, jeśli skonfigurowano usuwanie nietrwałe. Aby całkowicie usunąć wszystkie wiersze, w tym usunięte nietrwale, możesz zmienić to:

(new Model)->newQueryWithoutScopes()->forceDelete()

4

Wydaje się, że najlepszym sposobem wykonania tej operacji w programie Laravel 3jest użycie Fluentinterfejsu do obcięcia tabeli, jak pokazano poniżej

DB::query("TRUNCATE TABLE mytable");

2

Możesz wypróbować tę jedną linijkę, która zachowuje również miękkie usuwanie:

Model::whereRaw('1=1')->delete();


0

Podobnie jak w przypadku odpowiedzi Travisa Vignona, zażądałem danych z wymownego modelu i jeśli warunki były prawidłowe, musiałem albo usunąć, albo zaktualizować model. Skończyło się na tym, że otrzymałem minimalne i maksymalne pole zwrócone przez moje zapytanie (na wypadek, gdyby do tabeli dodano inne pole, które spełniałoby moje kryteria wyboru) wraz z pierwotnymi kryteriami wyboru, aby zaktualizować pola za pomocą jednego surowego zapytania SQL (jak w przeciwieństwie do jednego wymownego zapytania na obiekt w kolekcji).

Wiem, że użycie surowego SQL narusza filozofię pięknego kodu Laravels, ale trudno byłoby znieść setki zapytań zamiast jednego.


0

Może zrobić pętla też ...

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

Technicznie tak ... ale IMO wydaje się trochę niepotrzebne, ponieważ istnieją lepsze opcje pojedynczego zapytania.
Pete

@Pete, wiem ... inni już udzielili odpowiedzi ... próbowałem odpowiedzieć na inną możliwą metodę ...
Sam Solomon

1
To faktycznie działa dla mnie, ponieważ planuję archiwizować Modele w kolekcji na podstawie określonych reguł, ale także usuwać je z tej codziennie aktywnej tabeli.
James Perih,

-2

Rozwiązanie współpracujące z Lumenem 5.5 z ograniczeniami kluczy obcych:

$categories = MusicCategory::all();
foreach($categories as $category)
{
$category->delete();

}
return response()->json(['error' => false]);
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.