論理削除(ソフトデリート)と物理削除
物理削除
通常の削除、データベースから削除される
復元したり削除されたデータを参照することができなくなる
論理削除(ソフトデリート)
実際にはデータを削除せずに、削除されたと見なすこと
削除フラグのカラムを設定することで削除しているかのように扱うこと
Laravelにおけるソフトデリート
論理削除をするテーブルにdeleted_atカラムを作り(削除フラグになる)
deleted_atカラムに日時が挿入されていれば削除したものとして扱う
Laravelのソフトデリート設定方法
①論理削除するテーブルにdeleted_atカラムを追加する
マイグレーションファイルに以下の記述をする
マイグレーションファイル
$table->softDeletes();
②対象のモデルファイルにIlluminate\Database\Eloquent\SoftDeletesトレイトを追加する
Model
use Illuminate\Database\Eloquent\SoftDeletes; //追記
class User extends Model
{
use SoftDeletes; // 追記
}
③コントローラーファイルにソフトデリート処理を記載して完了
Controller
$user = User::findOrFail($id);
$user->delete(); // usersテーブルのdeleted_atカラムにタイムスタンプが挿入される
※物理削除
$user = User::findOrFail($id);
user->forceDelete(); // userテーブルからデータが削除される
その他の機能
ソフトデリートしたデータの取得
//deleted_atに値が入っているものを取得
$soft_delete_users = User::onlyTrashed()->get();
ソフトデリートしたデータの復元
$soft_delete_users = User::onlyTrashed()->get();
$soft_delete_users->restore(); // deleted_atカラムにnullを設定する
ソフトデリートしたデータも含めて全データを取得
$all_users = User::withTrashed()->get();
ソフトデリートしたデータのみ取得
$soft_delete_users = User::onlyTrashed()->get();
リレーション先のデータも含めてソフトデリートする
リレーション先のデータも含めて物理削除する場合
$table->foreignId('user_id')->constrained()// 外部キーの設定
->onDelete('cascade')
// 親テーブルが削除されたら自動的に削除できる設定
->onUpdate('cascade');
// 親テーブルが更新されたら子テーブル内の一致する行を自動的に更新する設定
この状態で親テーブルのデータを物理削除すると子テーブルの一致するuser_idを持つデータも自動的に消える
※しかし、ソフトデリートした場合は子テーブルのデータはソフトデリートされていなかった
解決策
laravel-soft-cascadeライブラリを使用する
①composerでインストール
composer require askedio/laravel-soft-cascade
②一緒にソフトデリートしたいデータの親テーブルのModelファイルに以下の記述を行う
Model
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, SoftDeletes;
use \Askedio\SoftCascade\Traits\SoftCascadeTrait; //追記
protected $softCascade = ['attendances'];// 追記(削除したいリレーションを配列で指定する)
// リレーションが複数ある場合は['attendances', ['comment']]のように複数指定できる
これでリレーション先のデータもソフトデリートできるようになった!
参考