Laravel論理削除&& リレーション先のデータも一括削除

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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です