Ccmmutty logo
Commutty IT
0 pv2 min read

Laravel Blueprintマクロによる共通カラム定義の問題点

https://picsum.photos/seed/515b4d4f802b4a59b96ed830084e83d6/1200/630

検索で一番最初に出てくるBlueprintマクロによる共通カラム定義の問題点

LaravelのBlueprintマクロは通常AppServiceProviderのboot()メソッドなどで登録されるため、アプリケーションの全リクエスト(HTTP、API、CLIなど)で読み込まれてしまうのがデフォルトの挙動です。
つまり、マイグレーション以外の場面でもマクロ登録処理が実行されてしまいます。

起こり得る弊害

  • マクロはマイグレーション時にしか使わないにもかかわらず、毎回のHTTPリクエストで登録処理が走るのは無駄でありパフォーマンス低下に繋がる。
  • BlueprintマクロはDBスキーマ定義に関係するもののため、Webリクエストのライフサイクルに含めるのは設計上も不自然であり責務の分離が曖昧になる。

対処法

1. BaseMigrationクラスを定義して継承する

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

abstract class BaseMigration extends Migration
{
    protected function addCommonColumns(Blueprint $table)
    {
        $table->timestamps();
        $table->softDeletes();
    }
}
class CreateUsersTable extends BaseMigration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $this->addCommonColumns($table); // 共通カラムを追加
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

2. 実行中の環境判定を用いてArtisanコマンド実行時のみマクロを登録

use Illuminate\Support\Facades\App;

public function boot()
{
    if (App::runningInConsole()) {
        Blueprint::macro('addCommonColumns', function () {
            $this->timestamps();
            $this->softDeletes();
        });
    }
}

Discussion

コメントにはログインが必要です。