Laravelの削除には、物理削除・論理削除があります。
物理削除はDBのレコードから削除します。対して、論理削除はEloquentでの抽出などには含まれないが、データベース上には存在し続けます。
後ほど後述しますが、”deleted_at” (timestamp型) を追加、SoftDeletesトレイとを追加することによって利用出来ます。
①:論理削除の設定 / 実施 / 復元
Usersテーブルに論理削除の設定を追加していきます。
①-1:migrationでカラムを追加
php artisan make:migration add_softdelete_to_users_table --table=users
migrationファイルは、upに$table->softDeletes();を追加します。
downにはdeleted_atを追加しています。
これは、$table->softDeletes();を追加することによって、カラム自体はdeleted_atが追加されるためです。
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class AddSoftdeleteToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('deleted_at'); }); } }
①-2:Model で Userで softDelet トレイトを追加
<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; use Illuminate\Database\Eloquent\SoftDeletes;// 追加 class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; use SoftDeletes; // 追加 //以下省略//
これで、論理削除の準備は完了です。
①-3:論理削除の実施
削除方法は、物理削除と同じです。ただし、DB::ファザードでは有効ではありません。Eloquentを利用した処理によるのでご注意を。
Controllerにて、
$user = User::find($id); $user->delete();
上記にて、論理削除が実施されます。
DBを見て頂くと、
deleted_atカラムに、削除したtimestampが記述されていると思います。これで論理削除完了です。 ( 論理削除されていないデータは、deleted_atがnullです。 )
①-4:論理削除されたデータを復元
restore() メソッドにて復元出来ます。 ただし、論理削除したデータを抽出してください。 User::find($id)では、論理削除したデータは抽出出来ません。(むしろ、これで抽出出来なくするために論理削除した訳ですので.)
下記で復元出来ます。
$user = User::onlyTrashed()->find($id)->restore();
②:論理削除時にリレーション先のデータを削除
論理削除時にリレーション先のデータを削除していきます。
上記までの処理を継続して、Userを利用していきます。
前提としては、Userにリレーションが設定していることを前提とします。
<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; use Illuminate\Database\Eloquent\SoftDeletes; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; use SoftDeletes; // //あいだ省略 // public function comment() { return $this->hasMany(Comment::class, 'user_id', 'id'); } public function post() { return $this->hasMany(Post::class, 'user_id', 'id'); }
Userが削除された際に、紐付いているcommentデータ、postデータも一緒に削除されるようにします。
class User に追加していきます。
<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; use Illuminate\Database\Eloquent\SoftDeletes; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; use SoftDeletes; // //あいだ省略 // /** * Userの削除に連動して、リレーション先のデータも削除 */ protected static function boot() { parent::boot(); static::deleting(function ($user) { $user->comment()->delete(); $user->post()->delete(); }); } public function comment() { return $this->hasMany(Comment::class, 'user_id', 'id'); }
上記設定にて、論理削除時に、リレーション先のデータも一緒に削除されます。
$user = User::find($id);
$user->delete();
■参考サイト
リレーション先の削除に関して、下記のサイト参考にさせて頂きました。