💬

Laravel DB Migration 12 Tips

2022/08/03に公開

Laravel Migrations: 12 Useful Tips in 12 Minutes -- youtube のメモ書き

laravel の6あたりで知識が止まってて、意外と migration や db まわりに変更があったのに今更知ったので、それのピックアップ。

DB リレーション

外部キーを張る時に foreign()->references('id')->on('books') としていたのが foreignId('book_id')->constrained() ですむようになった。

see : Foreign Key Constraints -- laravel.com

旧コード

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

Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');
 
    $table->foreign('user_id')->references('id')->on('users');
});

foreignId を使ったコード

書き方はいくつかあります。

ただ constrained を使う時は、それだけを使った時は unsigned bigint のカラムが追加されるだけっぽいです。バージョンによって微妙に挙動が違うかもしれない。

  1. テーブル名はカラム名の先頭句にあるので指定しないパターン
Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained();
});
  1. テーブル名は明示的に指定する
Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained('user');
});
  1. 関連付けに update/delete 成約をつける。

->constrained() のみでは成約はつかないっぽいので、update/delete に cascade 制約をつける。

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')
      ->constrained('user')
      ->onUpdate('cascade')
      ->onDelete('cascade');
});
  1. nullable化

これには注意が必要で、 必ず constrainted より前に実行させる 必要がある。

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')
      ->nullable()
      ->constrained();
});

autoincrement が UnsignedBigInteger に変更

$table->increments() で Auto_Increment が入ります。Laravel5.8 あたりまではカラムの型は UnsignedInteger でしたが、6.0 以降は BigUnsignedInteger になります。

Migration の順番

migration の順番はファイル名で決まります。
migrations/ ディレクトリに先頭はタイムスタンプ( YYYY_MM_dd_ss といった形)になっています。 このタイムスタンプを書き換えて、順番を操作してください。

Migration のチェック

Migration の状態はコマンド migrate:status を実行して確認ができます。手元で試した限りでは、表示形式はバージョンによって異なるみたいです。

> php artisan migrate:status
+------+-------------------------------------------------------------------+-------+
| Ran? | Migration                                                         | Batch |
+------+-------------------------------------------------------------------+-------+
| Yes  | 2019_08_07_074124_development_schema_running                      | 1     |
...

Timestamp 型のデフォルト値

$table->timestamp('review_date')->default('now') は動きません。 NOW() は MySQL 等では動かないからです。
$table->timestamp('review_date')->useCurrent() を使うと良いみたいです。

もし更新した時を保持する時は useCurrentOnUpdate() を使うと良いみたいです。

see : column-modifiers -- laravel.com

作られたばかりの Migration File を変更する

stub を変更する事になる。 php artisan stub:publish を実行して、 stubs/migration_create.stub ファイルが作成されます。

デフォルトでは下記のような感じのファイルです。これを変更して保存し、再度 php artisan make:migration を実行すれば変更された内容を元に migration ファイルを作成します。

stubs/migration_create.stub
<?php

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

class {{ class }} extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('{{ table }}', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('{{ table }}');
    }
}

Single SQL File

個人的には、あまりつかわない。

php artisan schema:dump を実行すれば schema/~.dump ファイルができます。少し古いバージョンのときは databases/schema/~-schema.dump になります。

これにはテーブルのスキーマーと、db migration のデータのみ書き出されます。

Drop Multi Column

$table->dropColumn() の引数は配列にでき、複数カラムを削除する時はそれらを引数の配列に入れて削除することができます。

Rollback or refresh x step

migrate:rollback --step=3 は過去三回のマイグレーションをロールバックする処理を実行します。一方で migrate:refresh --step=3 は過去三回のマイグレーションをロールバックする処理をした後、通常のマイグレーションを実行します。もし開発中で単にマイグレーションをやり直したい時は migrate:refresh の方が良いです。

AutoIncrement の開始値を指定

$table->id()->from(100) とすれば、100 番から開始が始まります。

Make Migration underscore vs space

実は php aritsan migrate add_name_column_to_aqualium の実行結果と php artisan migrate "add name column to aqualium" は同じ実行結果になります。

Discussion