Як видалити всі рядки з таблиці за допомогою Красномовних?


135

Моя здогадка полягала у використанні наступного синтаксису:

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

Але це не вийшло. Я впевнений, що це дуже просто, але я шукав документацію з цього приводу і не можу її знайти!

Відповіді:


279

Причина MyModel::all()->delete()не працює в тому, що all()фактично вимикає запит і повертає колекцію красномовних об'єктів.

Можна скористатися методом усікання, це працює для Laravel 4 і 5:

MyModel::truncate();

Це скидає всі рядки з таблиці без реєстрації окремих видалень рядків.


1
Я додав рішення Laravel 3 до свого питання для майбутніх читачів.
Піт

39
Приємно. Це також працює на Laravel 5, якщо хтось ще гуглів сам у 2016 році.
Самілес

14
Примітка: усікання () також скидає будь-який лічильник AUTO_INCREMENT (також зауважте, що ви не можете вкорочувати таблиці, які мають обмеження зовнішніх ключів.)
Вільям Туррелл

10
FYI: Turncate не спричинить видалення подій.
Fusion

1
Якщо ви дійсно хочете використовувати MyModel::all()->delete(), використовуйтеforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl

70

Розчин Laravel 5.2+ .

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

Просто візьміть основного будівельника з назвою таблиці і робіть все, що завгодно. Не може бути охайніше.

Розчин Laravel 5.6

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

9
У випадку, якщо когось іншого не бентежить, чому це працює, клас Model пересилає методи Builder за допомогою магічного методу __call тут . Оскільки в самому класі моделі є метод видалення, виклик Model :: delete () викликає метод Model, коли ви дуже хочете метод Builder. Отже, щоб отримати явно конструктор, ви можете використовувати getQuery ().
kevinAlbs

Це також не видаляє пов'язані таблиці, якщо ви цього хочете.
Terje Nesthus

Це змусить видалити всі записи, незалежно від того,
включено

Модель :: whereNotNull ('id') -> delete (); - буде видалено м'яке видалення, коли м'яке видалення ввімкнено
shalini

61

Ви можете використовувати, 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 ::
nespremned

ви також можете використовувати Schema :: disabledForeignKeyConstraints (); & Схема :: enableForeignKeyConstraints ();
Елеазар Ресендес

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 Було б дуже корисно вказати на різницю. Я також міг би додати це до своєї відповіді .
giannis christofakis

4
TRUNCATE не можна використовувати в транзакції, оскільки ROLLBACK на нього не впливає. У цьому випадку цього можна досягти за допомогою (новий 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 '%%'який відповідає всім рядкам таблиці, видаляючи таким чином все.
Хкан

Це привело мене в дорогу. Я закінчив робити pluck () на іншій моделі, щоб отримати масив потрібних мені ідентифікаторів, а потім використав цей масив, щоб видалити всі записи з моєї моделі whereInметодом: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC

9

Я хотів додати ще один варіант для тих, хто потрапляє до цієї теми через Google. Мені потрібно було досягти цього, але хотів зберегти своє значення автоматичного збільшення, яке truncate()скидається. Я також не хотів DB::нічого використовувати, тому що хотів оперувати безпосередньо від об'єкта моделі. Отже, я пішов з цим:

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

Очевидно, що стовпець повинен буде насправді існувати, але в стандартній нестандартній красномовній моделі idстовпець існує і ніколи не буває нульовим. Я не знаю, чи це найкращий вибір, але це працює в моїх цілях.


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 \ База даних \ Красномовний \ Модель :: delete () не повинен називатися статично, вважаючи $ це з несумісного контексту

Але це працює:

(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 порушує філософію прекрасної філософії коду, але і т. Д. Важко буде переповнити сотні запитів замість одного.


0

Можна зробити петля теж ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

Технічно так ... але IMO здається трохи непотрібним, оскільки є кращі варіанти одного запиту.
Піт

@ Пете я знаю .. інші вже давали свої відповіді ... я намагався відповісти на інший можливий спосіб зробити ..
Сем Соломон

1
Це насправді працює для мене, оскільки я планую архівувати Моделі колекції на основі конкретних правил, а також очищати їх від тієї щоденної таблиці.
Джеймс Перих

-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.