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

94

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

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

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

Теги:
eloquent
laravel-4

13 ответов

157
Лучший ответ

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

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

MyModel::truncate();

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

  • 0
    Круто, не знал об этом! Спасибо! Просто из любопытства (и для будущих читателей) есть ли способ сделать подобное в Laravel 3? Или просто нет поддерживаемого способа удаления всех строк в таблице в Laravel 3 (кроме обращения к PDO или чему-то еще)?
  • 1
    Я добавил решение Laravel 3 в свой вопрос для будущих читателей.
Показать ещё 7 комментариев
47

Вы можете использовать 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 ()
45

Laravel 5. 2+ решение.

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

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

Решение Laravel 5.6

\App\Model::query()->delete();
  • 8
    В случае , если кто - то был смущен о том, почему это работает, класс Model перенаправляет методы в Builder через __call волшебный метод здесь . Поскольку сам класс модели имеет метод delete, вызов Model :: delete () вызывает метод Model, когда вам действительно нужен метод Builder. Таким образом, чтобы получить конструктор явно, вы можете использовать getQuery ().
  • 0
    Это также не удаляет связанные таблицы, если вы этого хотите.
Показать ещё 2 комментария
22

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

// 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 Было бы очень полезно указать разницу. Я мог бы также добавить это к своему ответу .
Показать ещё 1 комментарий
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 '%%' который совпадает со всеми строками в таблице, таким образом удаляя все.
  • 0
    Это заставило меня на моем пути. Я закончил делать pluck () для другой модели, чтобы получить массив нужных мне идентификаторов, а затем использовал этот массив для удаления всех записей из моей модели, используя метод whereIn : $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
8

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

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

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

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

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

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

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

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

Но это работает:

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

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

(new Model)->newQueryWithoutScopes()->forceDelete()
  • 0
    Большое спасибо! :)
4

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

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

Вы также можете использовать силу Eloquent, делая это;

MyModel::get()->each->delete();
0

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

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

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

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

}
return response()->json(['error' => false]);
0

Можно сделать foreach loop..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}
  • 0
    Технически да ... но IMO кажется немного ненужным, так как есть лучшие варианты для одного запроса.
  • 0
    @ Пит, я знаю ... другие уже дали свои ответы ... я пытался ответить на другой возможный способ сделать ..
Показать ещё 1 комментарий
0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню