Bagaimana cara menghapus semua baris dalam tabel menggunakan Eloquent?

135

Dugaan saya adalah menggunakan sintaks berikut:

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

Tetapi itu tidak berhasil. Saya yakin ini sangat sederhana, tetapi saya telah mencari dokumentasi tentang masalah ini dan tidak dapat menemukannya!

Pete
sumber

Jawaban:

279

Alasannya MyModel::all()->delete()tidak berhasil adalah karena all()sebenarnya memadamkan kueri dan mengembalikan koleksi objek Eloquent.

Anda dapat menggunakan metode truncate, ini berfungsi untuk Laravel 4 dan 5:

MyModel::truncate();

Itu menjatuhkan semua baris dari tabel tanpa mencatat penghapusan baris individu.

bilalq
sumber
1
Saya telah menambahkan solusi Laravel 3 untuk pertanyaan saya, untuk pembaca masa depan.
Pete
39
Bagus. Ini juga berfungsi pada Laravel 5 jika ada orang lain yang menggunakan Google di 2016.
samiles
14
Catatan: truncate () juga menyetel ulang setiap penghitung AUTO_INCREMENT (juga perhatikan Anda tidak dapat memotong tabel yang memiliki batasan kunci asing.)
William Turrell
10
FYI: Turncate tidak akan memicu penghapusan acara.
Fusion
1
Jika Anda benar-benar ingin menggunakan MyModel::all()->delete(), gunakanforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl
70

Solusi Laravel 5.2+ .

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

Hanya ambil pembangun yang mendasari dengan nama tabel dan lakukan apa pun. Tidak bisa lebih rapi dari itu.

Laravel 5.6 solusi

\App\Model::query()->delete();
Yauheni Prakopchyk
sumber
9
Jika ada orang lain yang bingung tentang mengapa ini bekerja, kelas Model meneruskan metode ke Builder melalui metode sihir __call di sini . Karena kelas model itu sendiri memiliki metode hapus, memanggil Model :: delete () memanggil metode Model, ketika Anda benar-benar menginginkan metode Builder. Jadi untuk mendapatkan pembuat secara eksplisit, Anda dapat menggunakan getQuery ().
kevinAlbs
Ini juga tidak menghapus tabel terkait jika Anda menginginkannya.
Terje Nesthus
Ini akan memaksa menghapus semua catatan, terlepas dari apakah penghapusan lunak dihidupkan atau dimatikan
shalini
Model :: whereNotNull ('id') -> delete (); - akan melakukan soft delete ketika soft delete ON
shalini
61

Anda dapat menggunakan Model::truncate()jika Anda menonaktifkan foreign_key_checks(saya berasumsi Anda menggunakan MySQL).

DB::statement("SET foreign_key_checks=0");
Model::truncate();
DB::statement("SET foreign_key_checks=1");
Fortex
sumber
2
Di Laravel 4, Anda menggunakan DB :: tidak siap ()
swdev
Anda juga dapat menggunakan Skema :: disableForeignKeyConstraints (); & Skema :: enableForeignKeyConstraints ();
Eleazar Resendez
33

Saya telah melihat kedua metode telah digunakan dalam file seed.

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

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

//or

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

Meskipun Anda tidak dapat menggunakan yang pertama jika Anda ingin mengatur kunci asing .

Tidak dapat memotong tabel yang dirujuk dalam batasan kunci asing

Jadi mungkin ide yang baik untuk menggunakan yang kedua.

Giannis christofakis
sumber
2
deletejelas tidak sama dengan itu truncate.
Joel Mellon
2
@sudopeople Akan sangat membantu untuk menunjukkan perbedaannya. Saya juga bisa menambahkannya ke jawaban saya .
giannis christofakis
4
TRUNCATE tidak dapat digunakan dalam transaksi, karena tidak terpengaruh oleh ROLLBACK. Dalam hal ini, ini dapat dicapai dengan (MyModel baru) -> newQuery () -> delete ().
hammurabi
12

Ada cara tidak langsung:

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

Contoh:

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

Informasi pembuat kueri laravel: https://laravel.com/docs/5.4/queries

Rejaul
sumber
1
@aschipfl tidak banyak menjelaskan sebenarnya. Kode menjalankan SQL DELETE FROM users WHERE id LIKE '%%'yang cocok dengan semua baris dalam tabel, sehingga menghapus semuanya.
Hkan
Ini membuat saya dalam perjalanan. Saya akhirnya melakukan pemetikan () pada model lain untuk mendapatkan larik ID yang saya butuhkan, kemudian menggunakan larik itu untuk menghapus semua catatan dari model saya menggunakan whereInmetode: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC
9

Saya ingin menambahkan opsi lain untuk mereka yang mendapatkan utas ini melalui Google. Saya perlu melakukan ini, tetapi ingin mempertahankan nilai kenaikan otomatis yang truncate()diatur ulang. Saya juga tidak ingin menggunakan DB::apa pun karena saya ingin beroperasi langsung dari objek model. Jadi, saya pergi dengan ini:

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

Jelas kolom harus benar-benar ada, tetapi dalam model Eloquent out-of-the-box standar, idkolom ada dan tidak pernah nol. Saya tidak tahu apakah ini pilihan terbaik, tetapi ini berfungsi untuk tujuan saya.

lookitsatravis
sumber
Model::delete();akan mencapai hal yang sama.
Leng
5
Sayangnya Model::delete()melempar pengecualian Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, setidaknya di Laravel 5.0.
Dave James Miller
6

Saya tidak dapat menggunakan Model::truncate()karena itu akan kesalahan:

SQLSTATE [42000]: Kesalahan sintaksis atau pelanggaran akses: 1701 Tidak dapat memotong tabel yang dirujuk dalam batasan kunci asing

Dan sayangnya Model::delete()tidak berfungsi (setidaknya di Laravel 5.0):

Metode non-statis Illuminate \ Database \ Eloquent \ Model :: delete () tidak boleh dipanggil secara statis, dengan asumsi $ this dari konteks yang tidak kompatibel

Tetapi ini berhasil:

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

Itu akan menghapus semua baris secara lunak, jika Anda memiliki pengaturan penghapusan-lunak. Untuk sepenuhnya menghapus semua baris termasuk yang terhapus dengan lembut, Anda dapat mengubahnya menjadi ini:

(new Model)->newQueryWithoutScopes()->forceDelete()
Dave James Miller
sumber
4

Cara terbaik untuk menyelesaikan operasi ini Laravel 3adalah dengan menggunakan Fluentantarmuka untuk memotong tabel seperti yang ditunjukkan di bawah ini

DB::query("TRUNCATE TABLE mytable");
Pete
sumber
2

Anda dapat mencoba one-liner ini yang menjaga soft-delete juga:

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

solusi sederhana:

 Mymodel::query()->delete();
ali filali
sumber
0

Dalam nada yang mirip dengan jawaban Travis vignon, saya memerlukan data dari model fasih, dan jika kondisinya benar, saya harus menghapus atau memperbarui model. Saya akhirnya mendapatkan bidang minimum dan maksimum saya akan dikembalikan oleh permintaan saya (kalau-kalau bidang lain ditambahkan ke tabel yang akan memenuhi kriteria pilihan saya) bersama dengan kriteria seleksi asli untuk memperbarui bidang melalui satu permintaan SQL mentah (seperti menentang satu kueri fasih per objek dalam koleksi).

Saya tahu penggunaan SQL mentah melanggar filosofi kode indah laravel, tapi itu akan sulit untuk mencerna ratusan pertanyaan di tempat satu.

Sidney
sumber
0

Bisa melakukan a lingkaran juga ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}
Sam Solomon
sumber
Secara teknis ya ... tapi IMO yang tampaknya agak tidak perlu karena ada opsi permintaan tunggal yang lebih baik.
Pete
@Pete saya tahu .. orang lain sudah memberikan jawaban mereka ... saya sedang mencoba untuk menjawab metode lain yang mungkin untuk dilakukan ..
Sam Solomon
1
Ini sebenarnya bekerja untuk saya, karena saya berencana untuk mengarsipkan Model dalam koleksi berdasarkan aturan tertentu, tetapi juga menghapusnya dari tabel yang aktif sehari-hari.
James Perih
-1

Solusi yang bekerja dengan Lumen 5.5 dengan batasan kunci asing:

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

}
return response()->json(['error' => false]);
Alain Berrier
sumber