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();
■参考サイト
リレーション先の削除に関して、下記のサイト参考にさせて頂きました。
https://shinyasunamachi.com/blog/Laravel8%E3%81%A7%E8%A6%AA%E3%82%92%E8%AB%96%E7%90%86%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%82%89%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E5%85%88%E3%82%82%E8%AB%96%E7%90%86%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B