エラー体験記 laravelでのマイグレーションの手順

前置き

本日のお題は、「laravelでのマイグレーションの手順」です。

最近、phpフレームワークの一つであるlaravelを利用したアプリ開発を勉強中です。

その過程でファイルのマイグレーションにかなり悪戦苦闘してしまったので、教訓として残しておきます。

前提条件

  • DBはsqliteを使用。
  • usersテーブルを作成し、ageカラム(not null制約あり)を追加したい。

手順概略

  • DBの作成
  • マイグレーションの実行
  • auth/uiの導入(必要に応じて)
  • doctrin/dbalの導入
  • nullableの状態で、ageカラムを追加
  • ageカラムをnullable(false)に変更

 

以下、手順を個別に解説していきます。

 

DBの作成

@.env

// ファイル内の記述を一部変更
// 変更前

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_SATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
// 変更後
DB_CONNECTION=sqlite

// 1行目を変更し、2行目以降を削除。

@ターミナル
sqlite3 database/dataabase.sqlite
// ターミナルがDB専用コマンド入力状態に変化
.tebleと.exitを入力

// DBが作成される。

 

マイグレーションの実行

@ターミナル

php artisan migrate

// usersテーブルが作成される

 

補足ですが、laravelではusersテーブル用のマイグレーションファイルは予め用意されています。

なので、何もモデルを作らずにマイグレーションを実行するだけでusersモデルが作成されます。

auth/uiの導入(必要な場合のみ)

auth/uiは、ログイン機能などを簡単に導入できるlaravelのパッケージです。

Ruby on rails でいうところのdeviseですね。

前述の通り、laravelでは何もしなくてもusersテーブルのマイグレーションファイルが用意さえれています。

しかし、auth/uiを用いることでログインなどの機能を簡単に導入することができるようになっています。

 

laravel/uiを利用する際には、

  • uiの導入
  • テーブル作成
  • パッケージのインストール
  • CSS/JSのビルド

が必要になります。

以下、順に解説していきます。

 

uiの導入

@ターミナル

composer require laravel/ui

 

テーブル作成

@ターミナル

php artisan ui vue(react) --auth

# vueかreactかはお好みで
php artisan migrate

# この時点でHomeControllerが作成される

 

パッケージのインストール

@ターミナル

npm install

 

CSS, JSのビルド

@ターミナル

npm run dev

# エラーが出ても再度runを行うことで解消される場合があります。

 

doctrine/dbalの導入

doctrin/dbalとは、カラムの設定を変更するためのパッケージのことです。

導入せずにいかに進んだ場合にはエラーが出るので気づくかとは思います。

f:id:keishiprogramming:20210911095249p:plain

@ターミナル

composer require doctrine/dbal

これだけです。

 

ageカラムの追加

@ターミナル

php artisan migration add_column_age_to_users

# カラムを追加するためのマイグレーションファイルを作成

 

@上記で生成されたマイグレーションファイル

public function up()
{
    schema::$table("users", function (Blueprint $table){
        $table->integer("age")->nullable();

        # 一旦はnullableで設定していることに注意(詳細後述)
    });
}
public function down()
{
    schema::$table("users", function (Blueprint $table){
        $table->dropClumn("age");
        # ロールバック時に行う処理(ここではカラムの削除)も記述
    });
}

 

@ターミナル

php artisan migrate

 

上記でも触れていますが、カラムにnot null制約をかけたい場合であっても一旦はnullableで設定する必要があります。

sqliteの仕様なのですが、後から追加するカラムに最初からnot null制約をかけておくことができないみたいです(テーブル作成と同時に作るカラムであれば問題ない)。

もしいきなりnot null制約をかけると以下のようなエラーになります。

f:id:keishiprogramming:20210911095032p:plain

なので一旦はnullを許可した状態でカラムを追加し、後からnot null 制約だけをかけることになります(手順については次項目)。

not null 制約が不要の場合はここで終了して問題ありません。

 

カラムをnullable(false)に変更

@ターミナル

php artisan make:migration modify_users_20210911 --table=users

# nullable(false)に変更するためのファイルを作成
# ファイル名は、modify_テーブル名_日付 --table=テーブル名

ファイル名についてはなんでも良いと解説されている場合が多いですが、タイプミスやテーブル名の指定漏れなどがあるとファイルの中身がおかしくなります。

私は一度、schema::table("users", function(Bluepront $table){ ~ の部分がごっそりと抜けたファイルができたことがありました。

ぱっと見で明らかに様子がおかしければ、新しくファイルを作り直した方が無難です。

話がそれましたが、以下、マイグレーションファイルの編集です。

 

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

pubic function up()
{
    Schema::table("users", function(Blueprint $table) {
        $table->integer("age")->nullable(false)->change();
       
# nullable(false)としていることに注意。
    });
}
public function down()
{
    Schema::table("users", function(Blueprint $table) {
        $table->integer->nullable()->change();
  # not null制約付与のロールバックなので、nullableの付与のみを記述。
    })+
}

 

@ターミナル

php artisan migrate

 

カラムの追加の処理は以下で終了です。

なかなかややこしいですね。