Laravelにはソフトデリート、復元、完全削除機能のためのメソッドが用意されています。
ただルート設定にクセがあり、意外とスムーズに設定できないことも。
ルート設定・モデル・コントローラー・ビュー部分の具体例をお見せしながら、
- 通常のデリートをソフトデリートに変更する方法
- 復元、完全削除機能を追加する方法
を分かりやすく解説します。
ソフトデリートと完全削除の違い
最初に、ソフトデリートとは何か、すこしだけ書きますね。
ソフトデリートは、論理削除ともいわれます。
実際にデータを削減せず、「削除したように見せている」だけの状態。
Laravelでいえば、delete_atカラムに日付が入った状態となります。

反対に完全に削除した状態は、物理削除と呼ばれます。
これは、データ自体がデータベースから消えてしまっている状態です。

ソフトデリートであれば復元できますが、完全削除は復元不可能です。

ユーザーが間違ってデータを削除してしまうのを避けたい場合には、ソフトデリート機能がおすすめ。
Laravelにソフトデリート機能を付ける方法

それではここから、Laravelにソフトデリート機能を付ける方法を解説します。
今回は【Text】モデルにソフトデリート機能を付けるとします。
既に通常のデリート機能がついていますが、これをソフトデリートに変更します。
① deleted_at カラムを追加
まずはdeleted_atカラムを追加します。
下記のようなコマンドを実行して、マイグレーションファイルを作成しましょう。
php artisan make:migration add_column_deleted_at_to_textx_table --table=texts
databaseフォルダの中のマイグレーションファイルを開きます。
function up に、$table->softDeletes(); を入れます。
public function up()
{
Schema::table('texts', function (Blueprint $table) {
$table->softDeletes();
});
}
function down に、 $table->dropSoftDeletes(); を入れます。
public function down()
{
Schema::table('texts', function (Blueprint $table) {
$table->dropSoftDeletes();
});
}
このあと php artisan migrate でマイグレートを実行します。
phpMyAdminにログインして、テーブルの最後にdeleted_atカラムが追加されているのを確認してください。

②モデルファイルの修正
次に、モデルファイルを修正します。
ファイルの上部に、下記を追加しておきます。
use Illuminate\Database\Eloquent\SoftDeletes;
class Text extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
③テストする
これでソフトデリート機能の追加終了です。
試しに、通常どおりデータを削除した後、データベースを確認してみてください。
deleted_atのカラムに日付が入った状態となっていれば成功。

Laravelではこの状態が「ソフトデリート」。
通常は、ソフトデリートされたデータは表示されません。
④ソフトデリートのデータを呼び出す方法
ソフトデリートしたデータを含めて、すべてのデータを表示したい場合には、withTrashedメソッドを使います。

Trashはゴミ箱って意味です。
捨てるって意味もあります。
下記のようにすると、ソフトデリート済みのデータもすべて含めて、$textsの中に代入できます。
【withTrashedを使ったコントローラー例】
public function index(Request $request){
$texts=Text::withTrashed()->get();
return view('text.index', compact('texts'));
}
ソフトデリート済みのデータのみ表示したい場合は、onlyTrashedメソッドを使います。
【onlyTrashedを使ったコントローラー例】
public function index(Request $request){
$texts=Text::onlyTrashed()->get();
return view('text.index', compact('texts'));
}
Laravelにソフトデリートから回復機能を付ける方法

ソフトデリートしたデータを元通りにしたい場合には、restoreメソッドを使います。
今回はblade.phpファイル上に「戻す」ボタンを追加します。
「戻す」ボタンを押すと、ソフトデリートしたデータが回復するという仕様にします。

① RouteServiceProviderの設定
通常通りのルート設定では、ソフトデリートしたデータは呼び出せません。
まずは RouteServiceProvider.phpの設定から行っておきます。
app/Providersの中のRouteServiceProvider.phpを開きます。
下記を加えておきましょう。
public function boot()
{
Route::bind('trashed_text', function ($id) {
return \App\Models\Text::onlyTrashed()->find($id);
});
}
ソフトデリートしたtextを ‘trashed_text’ とします。
なお、上記はLaravel8の書き方となります。
Laravel8では、モデルファイルがApp/Modelsの中に入っています。

モデルファイルの場所とモデルの名前によって、コードを変更してくださいね。
② ルート設定
次にpatchメソッドを使ってルート設定を行います。
通常は{text}とする部分を、trashed_text とします。
Route::patch('/text/restore/{trashed_text}', 'TextController@restore')->name('text.restore');
③ ビューの設定
次に、blade.phpファイルにボタンを用意しておきます。
<form method="post" action="{{route('text.restore', $text->id)}}">
@csrf
@method('patch')
<button type=”submit” class="btn btn-primary btn-block">戻す</button>
</form>
④コントローラーの設定
最後にコントローラーです。
ソフトデリートしたTextの中から今回のTextを呼び出し、restoreを実行します。
public function restore(Text $text){
Text::onlyTrashed()->where('id', $text->id)->restore();
return redirect()->route('text.softdelete');
}
以上で出来上がりです!
Laravelにソフトデリートから完全削除機能を付ける方法

ソフトデリートしたデータを完全に削除したい場合には、forcedeleteメソッドを使います。
今回はblade.phpファイル上に「削除」ボタンを追加します。
「削除」ボタンを押すと、ソフトデリートしたデータが完全に消えるという仕様にします。

① RouteServiceProviderの設定
restoreメソッドの時と同様、この設定が必要です。
app/Providersの中のRouteServiceProvider.phpを開き、下記を加えておきましょう。
既に追加済みの場合は、スキップしてください。
public function boot()
{
Route::bind('trashed_text', function ($id) {
return \App\Models\Text::onlyTrashed()->find($id);
});
}
② ルート設定
次にdeleteメソッドを使ってルート設定を行います。
通常は{text}とする部分を、trashed_text とします。
Route::delete('/text/forcedelete/{trashed_text}', 'TextController@forcedelete')->name('text.forcedelete');
③ ビューの設定
次に、blade.phpファイルにボタンを用意しておきます。
<form method="post" action="{{route('text.forcedelete', $text->id)}}">
@csrf
@method('DELETE')
<button type=”submit” class="btn btn-danger btn-block btn-delete">削除</button>
</form>
④コントローラーの設定
最後にコントローラーです。
ソフトデリートしたTextの中から今回のTextを呼び出し、restoreを実行します。
public function restore(Text $text){
Text::onlyTrashed()->where('id', $text->id)->forceDelete();
return redirect()->route('text.softdelete');
}
以上で完了。

ほとんどrestoreと同じですよね。
さいごに
完全に削除したくないデータには、ソフトデリート機能を付けておいたほうが安全です。
回復や完全削除機能を扱えるユーザーは、アドミンなど、限定しておいがほうが使いやすいかもしれません。
なお必要に応じて、処理のあとに「元に戻しました」など、メッセージもつけてくださいね。

メッセージの付け方は、こちらの記事で解説しています。
Laravelの便利機能、色々と使い倒していきましょうー♪



コメント