Laravelにはソフトデリート、復元、完全削除機能のためのメソッドが用意されています。
ただルート設定にクセがあり、意外とスムーズに設定できないことも。
ルート設定・モデル・コントローラー・ビュー部分の具体例をお見せしながら、
- 通常のデリートをソフトデリートに変更する方法
- 復元、完全削除機能を追加する方法
を分かりやすく解説します。
ソフトデリートと完全削除の違い
最初に、ソフトデリートとは何か、すこしだけ書きますね。
ソフトデリートは、論理削除ともいわれます。
実際にデータを削減せず、「削除したように見せている」だけの状態。
Laravelでいえば、delete_atカラムに日付が入った状態となります。
反対に完全に削除した状態は、物理削除と呼ばれます。
これは、データ自体がデータベースから消えてしまっている状態です。
ソフトデリートであれば復元できますが、完全削除は復元不可能です。
ユーザーが間違ってデータを削除してしまうのを避けたい場合には、ソフトデリート機能がおすすめ。
Laravelにソフトデリート機能を付ける方法
それではここから、Laravelにソフトデリート機能を付ける方法を解説します。
今回は【Text】モデルにソフトデリート機能を付けるとします。
既に通常のデリート機能がついていますが、これをソフトデリートに変更します。
① deleted_at カラムを追加
まずはdeleted_atカラムを追加します。
下記のようなコマンドを実行して、マイグレーションファイルを作成しましょう。
1 |
php artisan make:migration add_column_deleted_at_to_textx_table --table=texts |
databaseフォルダの中のマイグレーションファイルを開きます。
function up に、 $table->softDeletes(); を入れます。
1 2 3 4 5 6 |
public function up() { Schema::table('texts', function (Blueprint $table) { $table->softDeletes(); }); } |
function down に、 $table->dropSoftDeletes(); を入れます。
1 2 3 4 5 6 |
public function down() { Schema::table('texts', function (Blueprint $table) { $table->dropSoftDeletes(); }); } |
このあと php artisan migrate でマイグレートを実行します。
phpMyAdminにログインして、テーブルの最後にdeleted_atカラムが追加されているのを確認してください。
②モデルファイルの修正
次に、モデルファイルを修正します。
ファイルの上部に、下記を追加しておきます。
1 2 3 4 5 6 |
use Illuminate\Database\Eloquent\SoftDeletes; class Text extends Model { use SoftDeletes; protected $dates = ['deleted_at']; |
③テストする
これでソフトデリート機能の追加終了です。
試しに、通常どおりデータを削除した後、データベースを確認してみてください。
deleted_atのカラムに日付が入った状態となっていれば成功。
Laravelではこの状態が「ソフトデリート」。
通常は、ソフトデリートされたデータは表示されません。
④ソフトデリートのデータを呼び出す方法
ソフトデリートしたデータを含めて、すべてのデータを表示したい場合には、withTrashedメソッドを使います。
Trashはゴミ箱って意味です。
捨てるって意味もあります。
下記のようにすると、ソフトデリート済みのデータもすべて含めて、$textsの中に代入できます。
【withTrashedを使ったコントローラー例】
1 2 3 4 |
public function index(Request $request){ $texts=Text::withTrashed()->get(); return view('text.index', compact('texts')); } |
ソフトデリート済みのデータのみ表示したい場合は、onlyTrashedメソッドを使います。
【onlyTrashedを使ったコントローラー例】
1 2 3 4 |
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を開きます。
下記を加えておきましょう。
1 2 3 4 5 6 |
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 とします。
1 |
Route::patch('/text/restore/{trashed_text}', 'TextController@restore')->name('text.restore'); |
③ ビューの設定
次に、blade.phpファイルにボタンを用意しておきます。
1 2 3 4 5 |
<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を実行します。
1 2 3 4 |
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を開き、下記を加えておきましょう。
既に追加済みの場合は、スキップしてください。
1 2 3 4 5 6 |
public function boot() { Route::bind('trashed_text', function ($id) { return \App\Models\Text::onlyTrashed()->find($id); }); } |
② ルート設定
次にdeleteメソッドを使ってルート設定を行います。
通常は{text}とする部分を、trashed_text とします。
1 |
Route::delete('/text/forcedelete/{trashed_text}', 'TextController@forcedelete')->name('text.forcedelete'); |
③ ビューの設定
次に、blade.phpファイルにボタンを用意しておきます。
1 2 3 4 5 |
<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を実行します。
1 2 3 4 |
public function restore(Text $text){ Text::onlyTrashed()->where('id', $text->id)->forceDelete(); return redirect()->route('text.softdelete'); } |
以上で完了。
ほとんどrestoreと同じですよね。
さいごに
完全に削除したくないデータには、ソフトデリート機能を付けておいたほうが安全です。
回復や完全削除機能を扱えるユーザーは、アドミンなど、限定しておいがほうが使いやすいかもしれません。
なお必要に応じて、処理のあとに「元に戻しました」など、メッセージもつけてくださいね。
メッセージの付け方は、こちらの記事で解説しています。
Laravelの便利機能、色々と使い倒していきましょうー♪