Eloquentを使用してテーブルのすべての行を削除する方法は?


135

私の推測は、次の構文を使用することでした:

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

しかし、それはうまくいきませんでした。とてもシンプルだと思いますが、この件に関するドキュメントを検索したところ見つかりませんでした。

回答:


279

MyModel::all()->delete()動作しない理由は、all()実際にクエリを実行してEloquentオブジェクトのコレクションを返すためです。

あなたはtruncateメソッドを利用することができます、これはLaravel 4と5で動作します:

MyModel::truncate();

個々の行の削除をログに記録せずに、テーブルからすべての行を削除します。


1
今後の読者のために、質問にLaravel 3ソリューションを追加しました。
ピート

39
いいね。これは2016年に他の誰かがGoogleを使用している場合、Laravel 5でも機能します。– 2016
笑顔

14
注:truncate()は、AUTO_INCREMENTカウンターもリセットします(外部キー制約のあるテーブルを切り捨てることはできません。)
William Turrell

10
参考: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クラスは__callマジックメソッドを介してBuilderにメソッドを転送します。モデルクラス自体に削除メソッドがあるため、Builderメソッドが本当に必要なときに、Model :: delete()を呼び出すと、Modelメソッドが呼び出されます。したがって、ビルダーを明示的に取得するには、getQuery()を使用できます。
kevinAlbs 2016年

また、必要に応じて、関連するテーブルを削除しません。
Terje Nesthus 2017

ソフト削除がオンかオフかに関係なく、すべてのレコードを強制的に削除します
shalini

Model :: 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 ::
unprepared

Schema :: disableForeignKeyConstraints();を使用することもできます。&Schema :: enableForeignKeyConstraints();
Eleazar Resendez

33

シードファイルで両方の方法が使用されているのを見てきました。

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

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

//or

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

外部キーを設定したい場合は、最初のキーは使用できません。

外部キー制約で参照されているテーブルを切り捨てることはできません

したがって、2番目のものを使用することをお勧めします。


2
delete明らかに同じではありませんtruncate
Joel Mellon

2
@sudopeople違いを指摘すると本当に助かります。それを私の回答に追加することもできます
giannis christofakis 2014

4
TRUNCATEはROLLBACKの影響を受けないため、トランザクションでは使用できません。その場合、これは(新しいMyModel)-> newQuery()-> delete()で実現できます。
hammurabi 2014

12

間接的な方法があります:

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

例:

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

Laravelクエリビルダー情報:https : //laravel.com/docs/5.4/queries


1
@aschipflは実際に説明することはあまりありません。コードDELETE FROM users WHERE id LIKE '%%'は、テーブル内のすべての行に一致するSQL を実行し、すべてを削除します。
Hkan 2015年

これは私を途中で連れて行った。私はその後、アレイが使用して私のモデルからすべてのレコードを削除することを使用し、必要なIDのIの配列を取得するために別のモデルに摘むを()やってしまったwhereIn方法を: $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
キースDC

9

Google経由でこのスレッドにアクセスする人のために、別のオプションを追加したいと思いました。これを達成する必要がありましたが、truncate()リセットする自動インクリメント値を保持したいと考えました。またDB::、モデルオブジェクトから直接操作する必要があるため、何も使用しませんでした。だから、私はこれで行きました:

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

当然、列は実際に存在する必要がありますが、標準の標準のEloquentモデルでは、id列が存在し、nullになることはありません。これが最良の選択かどうかはわかりませんが、私の目的には適しています。


Model::delete();同じことを達成します。
Leng

5
残念ながら、少なくともLaravel 5.0ではModel::delete()例外がスローさNon-static method Illuminate\Database\Eloquent\Model::delete() should not be called staticallyれます。
Dave James Miller

6

Model::truncate()エラーになるので使用できませんでした:

SQLSTATE [42000]:構文エラーまたはアクセス違反:1701外部キー制約で参照されているテーブルを切り捨てることはできません

そして、残念ながらModel::delete()動作しません(少なくともLaravel 5.0では):

非互換メソッドから$ thisを想定して、非静的メソッドIlluminate \ Database \ Eloquent \ Model :: 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

Travis vignonの回答と同様に、雄弁なモデルからのデータが必要でした。条件が正しければ、モデルを削除または更新する必要がありました。(選択基準を満たす別のフィールドがテーブルに追加された場合)クエリによって返されたフィールドの最小値と最大値を取得し、元の選択基準とともに生のSQLクエリを介してフィールドを更新しました(コレクション内のオブジェクトごとに1つの雄弁なクエリとは対照的です)。

生のSQLの使用は美しいコード哲学に違反することは知っていますが、1つのクエリの代わりに何百ものクエリを処理するのは難しいでしょう。


0

できる ループも..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}

技術的にはそうですが、IMOは単一のクエリオプションの方が優れているため、少し不必要に思えます。
ピート、

@Pete知っています。他の人がすでに答えを出しています...私は他の可能な方法に答えようとしていました...
Sam Solomon

1
特定のルールに基づいてコレクション内のモデルをアーカイブすることを計画しているが、これは実際に機能しますが、その日アクティブなテーブルからそれらをクリアします。
James Perih 2016

-1

外部キー制約を使用してLumen 5.5を操作するソリューション:

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

}
return response()->json(['error' => false]);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.