Как удалить все строки в таблице с помощью Eloquent?


135

Я предполагал использовать следующий синтаксис:

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

Но это не сработало. Я уверен, что это очень просто, но я искал документацию по этой теме и не нашел!

Ответы:


279

Причина MyModel::all()->delete()неработоспособности заключается в том, что на all()самом деле запрос запускается и возвращает коллекцию объектов Eloquent.

Вы можете использовать метод truncate, это работает для Laravel 4 и 5:

MyModel::truncate();

Это удаляет все строки из таблицы без регистрации удаления отдельных строк.


1
Я добавил на свой вопрос решение Laravel 3 для будущих читателей.
— Pete

39
Ницца. Это работает и на Laravel 5, если в 2016 году кто-нибудь еще
— погуглиет.

14
Примечание: truncate () также сбрасывает любой счетчик AUTO_INCREMENT (также обратите внимание, что вы не можете усекать таблицы с ограничениями внешнего ключа.)
— Уильям Туррелл,

10
К вашему сведению: Turncate не будет запускать события удаления.
— Fusion

1
Если действительно хотите использовать MyModel::all()->delete(), используйтеforeach (MyModel::all() as $e) { $e->delete() }
— Ema4rl 02

70

Решение Laravel 5.2+ .

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

Просто возьмите базовый конструктор с именем таблицы и сделайте что угодно. Не может быть лучше этого.

Решение Laravel 5.6

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

9
В случае , если кто - то был смущен о том, почему это работает, модель перенаправляет класса методы к Builder с помощью метода волшебной __call здесь . Поскольку сам класс модели имеет метод удаления, вызов Model :: delete () вызывает метод Model, когда вам действительно нужен метод Builder. Итак, чтобы получить конструктор явно, вы можете использовать getQuery ().
— kevinAlbs 07

Это также не удаляет связанные таблицы, если вы этого хотите.
— Terje Nesthus

Это приведет к принудительному удалению всех записей, независимо от того,
— включено

Модель :: whereNotNull ( 'ID') -> Удалить (); - будет выполнять мягкое удаление, когда мягкое удаление включено
— shalini

62

Вы можете использовать, Model::truncate()если отключите foreign_key_checks(я предполагаю, что вы используете MySQL).

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

2
В Laravel 4 вы используете DB ::
— unprepared

вы также можете использовать Schema :: disableForeignKeyConstraints (); & Схема :: enableForeignKeyConstraints ();
— Eleazar

33

Я видел, что оба метода использовались в исходных файлах.

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

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

//or

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

Даже если вы не можете использовать первый, если хотите установить внешние ключи .

Невозможно усечь таблицу, указанную в ограничении внешнего ключа

Так что было бы неплохо использовать второй.


2
deleteочевидно, это не то же самое truncate.
— Джоэл Меллон

2
@sudopeople Было бы очень полезно указать на разницу. Я мог бы также добавить это к своему ответу .
— Яннис Кристофакис

4
TRUNCATE нельзя использовать в транзакции, поскольку на него не влияет ROLLBACK. В этом случае это может быть достигнуто с помощью (new MyModel) -> newQuery () -> delete ().
— Хаммурапи

12

Есть косвенный способ:

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

Пример:

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

Информация о построителе запросов Laravel: https://laravel.com/docs/5.4/queries


1
@aschipfl на самом деле особо нечего объяснять. Код запускает SQL, DELETE FROM users WHERE id LIKE '%%'который соответствует всем строкам в таблице, тем самым удаляя все.
— Hkan

Это поставило меня в путь. В итоге я выполнил pluck () на другой модели, чтобы получить массив необходимых мне идентификаторов, а затем использовал этот массив для удаления всех записей из моей модели с помощью следующего whereInметода: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
— Кейт

9

Я хотел добавить еще один вариант для тех, кто попадает в эту ветку через Google. Мне нужно было это сделать, но я хотел сохранить значение автоинкремента, которое truncate()сбрасывается. Я также не хотел DB::ничего использовать, потому что хотел работать непосредственно с объектом модели. Итак, я пошел с этим:

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

Очевидно, что столбец должен действительно существовать, но в стандартной готовой модели Eloquent idстолбец существует и никогда не имеет значения NULL. Не знаю, лучший ли это выбор, но он работает для моих целей.


Model::delete();выполнит то же самое.
— Ленг

5
К сожалению, Model::delete()выдает исключение Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, по крайней мере, в Laravel 5.0.
— Дэйв Джеймс Миллер

6

Я не смог использовать, так Model::truncate()как это вызвало бы ошибку:

SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1701 Невозможно усечь таблицу, на которую имеется ссылка в ограничении внешнего ключа

И, к сожалению Model::delete(), не работает (по крайней мере, в Laravel 5.0):

Нестатический метод Illuminate \ Database \ Eloquent \ Model :: delete () не должен вызываться статически, если $ this из несовместимого контекста

Но это действительно работает:

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

Это приведет к мягкому удалению всех строк, если у вас настроено мягкое удаление. Чтобы полностью удалить все строки, включая частично удаленные, вы можете изменить это:

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

4

Лучшим способом выполнения этой операции, по- Laravel 3видимому, является использование Fluentинтерфейса для усечения таблицы, как показано ниже.

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

2

Вы можете попробовать этот однострочник, который также сохраняет мягкие удаления:

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


0

Подобно ответу Трэвиса Виньона, мне потребовались данные из красноречивой модели, и если условия были правильными, мне нужно было либо удалить, либо обновить модель. Я получил минимальное и максимальное значение поля, возвращаемое моим запросом (в случае, если в таблицу было добавлено другое поле, которое соответствовало бы моим критериям выбора) вместе с исходными критериями выбора для обновления полей с помощью одного необработанного SQL-запроса (как в отличие от одного красноречивого запроса на объект в коллекции).

Я знаю, что использование необработанного SQL нарушает философию прекрасного кода Laravel, но было бы трудно переварить, возможно, сотни запросов вместо одного.


0

Может сделать петля тоже ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

Технически да ... но ИМО это кажется немного ненужным, поскольку есть лучшие варианты одиночного запроса.
— Пит

@Pete, я знаю ... другие уже дали свои ответы ... я пытался ответить другим возможным способом ...
— Сэм Соломон,

1
Это действительно работает для меня, так как я планирую архивировать модели в коллекции на основе определенных правил, но также очищать их из этой ежедневной активной таблицы.
— Джеймс Перих 06

-1

Решение, которое работает с Lumen 5.5 с ограничениями внешних ключей:

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

}
return response()->json(['error' => false]);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.