Eloquent kullanarak bir tablodaki tüm satırlar nasıl silinir?


136

Tahminim şu sözdizimini kullanmaktı:

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

Ama bu işe yaramadı. Eminim çok basittir, ancak konuyla ilgili belgeleri aradım ve bulamıyorum!

Yanıtlar:


280

Nedeni MyModel::all()->delete()işe yaramıyor çünkü all()aslında sorguyu ateşliyor ve bir Eloquent nesneleri koleksiyonu döndürüyor.

Kesik yöntemini kullanabilirsiniz, bu Laravel 4 ve 5 için çalışır:

MyModel::truncate();

Bu, tek tek satır silme işlemlerini günlüğe kaydetmeden tablodaki tüm satırları bırakır.


1
Gelecekteki okuyucular için soruma bir Laravel 3 çözümü ekledim.
Pete

39
Güzel. Bu, 2016'da başka biri Google'da arama yaparsa Laravel 5'te de işe yarar.
samiles

14
Not: truncate () ayrıca herhangi bir AUTO_INCREMENT sayacını da sıfırlar (ayrıca yabancı anahtar kısıtlamaları olan tabloları kesemeyeceğinizi unutmayın.)
William Turrell

10
Bilginize: Turncate, silme olaylarını tetiklemeyecektir.
Fusion

1
Gerçekten kullanmak istiyorsanız MyModel::all()->delete(), şunu kullanınforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl

70

Laravel 5.2+ çözümü.

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

Sadece altta yatan oluşturucuyu tablo adıyla alın ve her şeyi yapın. Bundan daha düzenli olamaz.

Laravel 5.6 çözümü

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

9
Bunun neden işe yaradığı konusunda başka birinin kafası karışmışsa, Model sınıfı yöntemleri __call sihirli yöntemiyle Oluşturucuya buradan iletir . Model sınıfının kendisinin bir silme yöntemi olduğundan, Model :: delete () çağrısı, Builder yöntemini gerçekten istediğinizde Model yöntemini çağırır. Bu nedenle oluşturucuyu açıkça almak için getQuery () kullanabilirsiniz.
kevinAlbs

Bu, isterseniz ilgili tabloları da silmez.
Terje Nesthus

Yazılımla silmenin açık veya kapalı olmasına bakılmaksızın tüm kayıtları silmeye zorlayacak
shalini

Model :: whereNotNull ( 'id') ->) (silme; - yazılımla silme AÇIK olduğunda yumuşak silme işlemi gerçekleştirecek
shalini

62

Sen kullanabilirsiniz Model::truncate()devre dışı eğer foreign_key_checks(ben MySQL kullanmak farz).

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

2
Laravel 4'te DB :: hazırlıksız ()
swdev

ayrıca Schema :: disableForeignKeyConstraints (); & Schema :: enableForeignKeyConstraints ();
Eleazar Resendez

33

Her iki yöntemin de tohum dosyalarında kullanıldığını gördüm.

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

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

//or

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

Yabancı anahtarlar ayarlamak istiyorsanız ilkini kullanamasanız bile .

Yabancı anahtar kısıtlamasında referans verilen bir tablo kesilemez

Bu yüzden ikincisini kullanmak iyi bir fikir olabilir.


2
deleteaçıkçası truncatesanki aynı değil .
Joel Mellon

2
@sudopeople Farkı belirtmek gerçekten yardımcı olur. Bunu cevabıma da ekleyebilirim .
giannis christofakis

4
TRUNCATE, ROLLBACK'ten etkilenmediği için bir işlemde kullanılamaz. Bu durumda, bu (yeni MyModel) -> newQuery () -> delete () ile gerçekleştirilebilir.
hammurabi

12

Dolaylı bir yol var:

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

Misal:

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

Laravel sorgu oluşturucu bilgileri: https://laravel.com/docs/5.4/queries


1
@aschipfl aslında açıklayacak pek bir şey yok. Kod DELETE FROM users WHERE id LIKE '%%', tablodaki tüm satırlarla eşleşen SQL'i çalıştırır ve böylece her şeyi siler.
Hkan

Bu beni yoluma çıkardı. Sonunda ihtiyacım olan kimliklerin bir dizisini elde etmek için başka bir modelde bir pluck () yaptım, ardından bu diziyi modelimden tüm kayıtları silmek için şu whereInyöntemi kullanarak kullandım : $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC

9

Bu konuya Google aracılığıyla ulaşanlar için başka bir seçenek eklemek istedim. Bunu başarmam gerekiyordu, ancak truncate()sıfırlanan otomatik artış değerimi korumak istedim . Ayrıca, DB::doğrudan model nesnesinin dışında çalışmak istediğim için hiçbir şey kullanmak istemedim . Ben de bununla gittim:

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

Açıktır ki sütunun gerçekten var olması gerekecek, ancak standart, kullanıma hazır Eloquent modelinde idsütun var ve hiçbir zaman boş değil. Bunun en iyi seçenek olup olmadığını bilmiyorum ama amaçlarım için işe yarıyor.


Model::delete();aynı şeyi başaracak.
Leng

5
Ne yazık ki , en azından Laravel 5.0'da Model::delete()bir istisna atıyor Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically.
Dave James Miller

6

Model::truncate()Hata oluşturacağı için kullanamadım :

SQLSTATE [42000]: Sözdizimi hatası veya erişim ihlali: 1701 Yabancı anahtar kısıtlamasında başvurulan bir tablo kesilemez

Ve maalesef Model::delete()çalışmıyor (en azından Laravel 5.0'da):

Statik olmayan yöntem Illuminate \ Database \ Eloquent \ Model :: delete (), $ this'in uyumsuz bağlamdan olduğu varsayılarak statik olarak çağrılmamalıdır

Ama bu işe yarıyor:

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

Yazılımla silme ayarınız varsa, bu tüm satırları yazılımla silecektir. Yazılımla silinenler dahil tüm satırları tamamen silmek için şuna değiştirebilirsiniz:

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

4

Bu işlemi gerçekleştirmenin en iyi yolu, aşağıda gösterildiği gibi tabloyu kesmek için arayüzün Laravel 3kullanılması gibi görünüyor.Fluent

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

2

Yumuşak silme işlemlerini de koruyan bu tek astarı deneyebilirsiniz:

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


0

Travis vignon'un cevabına benzer bir şekilde, anlamlı modelden veri istedim ve koşullar doğruysa, modeli silmem veya güncellemem gerekiyordu. Sorgum tarafından döndürülen minimum ve maksimum I alanını (seçim kriterlerimi karşılayacak başka bir alan eklenmesi durumunda) ve alanları bir ham SQL sorgusu ( koleksiyondaki nesne başına bir anlamlı sorguya karşılık).

Ham SQL kullanımının Laravel'in güzel kod felsefesini ihlal ettiğini biliyorum, ancak muhtemelen yüzlerce sorguyu bir yerine sindirmek zor olacaktır.


0

Yapabilir döngü de ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

Teknik olarak evet ... ama IMO, daha iyi tek sorgu seçenekleri olduğundan biraz gereksiz görünüyor.
Pete

@Pete biliyorum .. diğerleri zaten cevaplarını verdi ... diğer olası yöntemi cevaplamaya çalışıyordum ..
Sam Solomon

1
Koleksiyondaki Modelleri belirli kurallara göre arşivlemeyi ve aynı zamanda bunları günlük-aktif tablodan temizlemeyi planladığım için bu aslında benim için çalışıyor.
James Perih

-1

Yabancı anahtar kısıtlamalarıyla Lumen 5.5 ile çalışan çözüm:

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

}
return response()->json(['error' => false]);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.