Làm cách nào để xóa tất cả các hàng trong bảng bằng Eloquent?


135

Tôi đoán là sử dụng cú pháp sau:

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

Nhưng điều đó đã không làm việc. Tôi chắc chắn nó rất đơn giản, nhưng tôi đã tìm kiếm tài liệu về chủ đề này và không thể tìm thấy nó!

Câu trả lời:


279

Lý do MyModel::all()->delete()không hoạt động là vì all()thực sự bắn ra truy vấn và trả về một bộ sưu tập các đối tượng Eloquent.

Bạn có thể sử dụng phương pháp cắt ngắn, phương pháp này hoạt động cho Laravel 4 và 5:

MyModel::truncate();

Điều đó làm giảm tất cả các hàng từ bảng mà không ghi nhật ký xóa từng hàng.


1
Tôi đã thêm một giải pháp Laravel 3 cho câu hỏi của tôi, cho những độc giả tương lai.
Pete

39
Đẹp. Điều này cũng hoạt động trên Laravel 5 nếu có ai khác tự mình ở đây vào năm 2016.
samiles 18/03/2016

14
Lưu ý: truncate () cũng đặt lại bất kỳ bộ đếm AUTO_INCREMENT nào (cũng lưu ý rằng bạn không thể cắt các bảng có ràng buộc khóa ngoài.)
William Turrell

10
FYI: Turncate sẽ không kích hoạt xóa các sự kiện.
Hợp nhất

1
Nếu bạn thực sự muốn sử dụng MyModel::all()->delete(), hãy sử dụngforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl

70

Dung dịch Laravel 5.2+ .

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

Chỉ cần lấy trình xây dựng cơ bản với tên bảng và làm bất cứ điều gì. Không thể nào gọn gàng hơn thế.

Laravel 5,6 giải pháp

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

9
Trong trường hợp bất kỳ ai khác nhầm lẫn về lý do tại sao điều này hoạt động, lớp Model sẽ chuyển tiếp các phương thức đến Builder thông qua phương thức ma thuật __call ở đây . Vì bản thân lớp mô hình có một phương thức xóa, nên gọi Model :: xóa () gọi phương thức Model, khi bạn thực sự muốn phương thức Builder. Vì vậy, để có được trình xây dựng rõ ràng, bạn có thể sử dụng getQuery ().
kevinAlbs

Điều này cũng không xóa các bảng liên quan nếu bạn muốn điều đó.
Terje Nesthus

Nó sẽ buộc xóa tất cả các bản ghi, bất kể xóa mềm hay tắt
shalini

Mô hình :: whereNotNull ('id') -> xóa (); - sẽ xóa mềm khi xóa mềm là BẬT
shalini

61

Bạn có thể sử dụng Model::truncate()nếu bạn tắt foreign_key_checks(tôi giả sử bạn sử dụng MySQL).

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

2
Trong Laravel 4, bạn sử dụng DB ::
unprepared

bạn cũng có thể sử dụng Schema :: eacForeignKeyConstraint (); & Schema :: enableForeignKeyConstraint ();
Eleazar Resendez

32

Tôi đã thấy cả hai phương pháp đã được sử dụng trong các tập tin hạt giống.

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

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

//or

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

Mặc dù bạn không thể sử dụng khóa đầu tiên nếu bạn muốn đặt khóa ngoại .

Không thể cắt một bảng được tham chiếu trong một ràng buộc khóa ngoại

Vì vậy, nó có thể là một ý tưởng tốt để sử dụng cái thứ hai.


2
deleterõ ràng là không giống như truncatemặc dù.
Joel Mellon

2
@sudop People Sẽ thật sự hữu ích khi chỉ ra sự khác biệt. Tôi cũng có thể thêm nó vào câu trả lời của tôi .
gianni christofakis

4
TRUNCATE không thể được sử dụng trong giao dịch, vì nó không bị ảnh hưởng bởi ROLLBACK. Trong trường hợp đó, điều này có thể đạt được với (MyModel mới) -> newQuery () -> xóa ().
hammurabi

12

Có một cách gián tiếp:

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

Thí dụ:

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

Thông tin về trình tạo truy vấn của Laravel: https://laravel.com/docs/5.4/queries


1
@aschipfl không có nhiều để giải thích thực sự. Mã chạy SQL DELETE FROM users WHERE id LIKE '%%'khớp với tất cả các hàng trong bảng, do đó xóa mọi thứ.
Hkan

Điều này đã đưa tôi trên con đường của tôi. Cuối cùng tôi đã thực hiện một thao tác gảy () trên một mô hình khác để lấy một mảng ID tôi cần, sau đó sử dụng mảng đó để xóa tất cả các bản ghi khỏi mô hình của tôi bằng whereInphương thức: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC

9

Tôi muốn thêm một tùy chọn khác cho những người nhận được chủ đề này thông qua Google. Tôi cần phải thực hiện điều này, nhưng muốn giữ lại giá trị tăng tự động của mình mà truncate()đặt lại. Tôi cũng không muốn sử dụng DB::bất cứ thứ gì vì tôi muốn thao tác trực tiếp với đối tượng mô hình. Vì vậy, tôi đã đi với điều này:

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

Rõ ràng là cột sẽ phải thực sự tồn tại, nhưng trong một mô hình Eloquent tiêu chuẩn, vượt trội, idcột tồn tại và không bao giờ là null. Tôi không biết nếu đây là sự lựa chọn tốt nhất, nhưng nó hoạt động cho mục đích của tôi.


Model::delete();sẽ hoàn thành điều tương tự.
Leng

5
Thật không may, Model::delete()ném một ngoại lệ Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, ít nhất là trong Laravel 5.0.
Dave James Miller

6

Tôi không thể sử dụng Model::truncate()vì nó sẽ bị lỗi:

SQLSTATE [42000]: Lỗi cú pháp hoặc vi phạm truy cập: 1701 Không thể cắt một bảng được tham chiếu trong một ràng buộc khóa ngoài

Và thật không may Model::delete(), không hoạt động (ít nhất là trong Laravel 5.0):

Phương thức không tĩnh Illuminate \ Database \ Eloquent \ Model :: xóa () không nên được gọi là tĩnh, giả sử $ này từ ngữ cảnh không tương thích

Nhưng điều này không hoạt động:

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

Điều đó sẽ xóa mềm tất cả các hàng, nếu bạn đã thiết lập xóa mềm. Để xóa hoàn toàn tất cả các hàng, kể cả các hàng bị xóa mềm, bạn có thể thay đổi thành:

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

4

Cách tốt nhất để thực hiện thao tác này Laravel 3dường như là sử dụng Fluentgiao diện để cắt bớt bảng như dưới đây

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

2

Bạn cũng có thể thử loại lót này giúp bảo vệ các thao tác xóa mềm:

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


0

Theo cách tương tự với câu trả lời của Travis vignon, tôi đã yêu cầu dữ liệu từ mô hình hùng hồn và nếu điều kiện là chính xác, tôi cần phải xóa hoặc cập nhật mô hình. Tôi cố gắng nhận được trường tối thiểu và tối đa mà tôi đã trả về bởi truy vấn của mình (trong trường hợp một trường khác được thêm vào bảng đáp ứng tiêu chí lựa chọn của tôi) cùng với tiêu chí lựa chọn ban đầu để cập nhật các trường thông qua một truy vấn SQL thô (như trái ngược với một truy vấn hùng hồn cho mỗi đối tượng trong bộ sưu tập).

Tôi biết việc sử dụng SQL thô vi phạm triết lý mã đẹp, nhưng khó có thể kiểm tra được hàng trăm truy vấn thay cho một truy vấn.


0

Có thể làm một vòng lặp quá ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

Về mặt kỹ thuật thì có ... nhưng IMO có vẻ hơi bất cần vì có nhiều tùy chọn truy vấn tốt hơn.
Pete

@Pete tôi biết .. những người khác đã đưa ra câu trả lời của họ ... tôi đã cố gắng trả lời phương pháp khác có thể làm ..
Sam Solomon

1
Điều này thực sự hiệu quả với tôi, khi tôi dự định lưu trữ các Mô hình trong bộ sưu tập dựa trên các quy tắc cụ thể, nhưng cũng xóa chúng khỏi bảng hoạt động hàng ngày đó.
James Perih

0

Giải pháp làm việc với Lumen 5.5 với các ràng buộc khóa ngoài:

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

}
return response()->json(['error' => false]);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.