【Laravel/MySQL】レコードを論理削除(SoftDeletes)する

もくじ

論理削除と物理削除

違いについて詳しくは過去の記事から。

bonoponz.hatenablog.com

物理削除であればLaravelやDB上で特に何かする必要はありませんが、論理削除する場合は削除フラグを立てて削除されたかのように見せる必要があります。

そのため、論理削除を採用するならMySQL(DB)に削除フラグ用のカラムを追加します。

環境

  • Laravel 7.27.0
  • MySQL 8.0.21
  • PHP 7.3.11

今回、MySQLに作成したtestsというテーブルに論理削除を採用します。

マイグレーションファイル

まずはマイグレーションファイルを作成します。

bonoponz.hatenablog.com

すでにマイグレートしている場合は、初期化しましょう。

$ php artisan migrate:reset

初期化してからファイルの変更を行います。

class CreateTestsTable extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('tests', function (Blueprint $table) {
      $table->id();
      $table->string('name', 10);
      $table->integer('age');
      $table->string('sex', 10);
      $table->timestamps();
      $table->softDeletes(); // ★ 追記
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    // ★ 下記のように修正
    Schema::table('tests', function (Blueprint $table) {
      $table->dropSoftDeletes();
    });
  }
}

★のように修正することで論理削除のフラグを立てるカラムが出来上がります。

マイグレートしましょう。

$ php artisan migrate

ターミナルやGUIなどでDBのテーブルを確認すると、deleted_atカラムが追加されたことが確認できます。

f:id:bonoponz:20201125111829p:plain

モデル

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; // 追記

class Test extends Model
{
    use SoftDeletes;    // 追記
}

上記の記述で、Eloquentでのdeleteメソッドやdestroyメソッドが自動的に論理削除として扱われます。

bonoponz.hatenablog.com

削除実行

コントローラに削除のメソッドを追加して、 bladeからpostすると削除されるようにしてみます。

<form action="{{ route('softdelete.delete') }}" method="POST">
@csrf

  <div class="form-group">
    <select name="id" class="custom-select">
      <option>選択してください</option>
      <option value="0">0</option>
      <option value="1">1</option>
      <option value="2">2</option>
    </select>
  </div>

  <div class="form-group row justify-content-center">
    <button type="submit" name="send" class="btn btn-primary">送信</button>
  </div>
</form>
/**
 * ソフトデリートで削除する
 */
public function Delete(Request $request) {
  $test = Test::destroy($request->id);

  return redirect()->route('softdelete');
}

f:id:bonoponz:20201125204936p:plain

f:id:bonoponz:20201125204949p:plain

この場合選択して送信を押すと論理削除されます。選択した番号がidになっておりそのidを論理削除するメソッドです。

GUIで確認すると、レコード自体は存在しdelete_atがNULLから日付が変更され削除扱いとなっています。

f:id:bonoponz:20201125205011p:plain

参考URL

Laravel テーブル内のデータ削除を論理削除にする - Qiita