Laravel nullableとは|MigrationとValidationでの使い方

by

カテゴリー:

Laravelのnullableとは、対象のフィールドが「NULL(空)を許可する」ことを指定する仕組みです。ポイントは、同じnullableという言葉でもデータベース(Migration)とバリデーション(Validation)で役割が異なることです。

  • Migrationのnullable:DBのカラム定義で、その列にNULLを保存できるようにする(テーブル構造の話)
  • Validationのnullable:フォーム入力の検証で、値が空でもエラーにしない(入力チェックの話)

本記事では、この2つのnullableを混同しないように、それぞれの基本コードと実務での使い方、関連ルール(required / sometimes / present)との違いまで整理します。目的の箇所からすぐに読めるよう、以下のリンクを用意しました。

nullable属性とは

Laravelにおけるnullableとは、「NULL値(何も値がない状態)を許可する」ための識別子です。データベースのマイグレーションとバリデーションの両方で使われますが、扱う対象が異なります。

「null値」とは、文字列・数値・日付などの具体的な値ではなく、「何も設定されていない(未知・存在しない)」ことを表す特別な値です。nullableを指定すると、そのフィールドは具体的な値の代わりにnullを保持できるようになり、「アパート番号のように入力が任意な項目」などを正確に表現できます。

DBのnullableとValidationのnullableは別物

初心者がつまずきやすいのが、この2つは独立しているという点です。

  • DBカラムをnullable()にしても、Validationでrequiredにすれば空入力はエラーになる
  • 逆にValidationをnullableにしても、DB側がNOT NULL(nullable()未指定)ならnull保存時にSQLエラーになる

つまり「空を許可したい項目」は、DB(Migration)とValidationの両方でnullableを揃えるのが基本です。以降でそれぞれの書き方を見ていきます。

nullable属性を使うメリット

  1. データの正確性の向上:無効なデータやダミー値を避け、「存在しない/未知」をnullで正確に表現できる
  2. 柔軟なデータモデリング:必須ではない項目にnullableを設定でき、将来の拡張にも対応しやすい
  3. バリデーションの柔軟性:任意項目を「空ならスキップ、入力があれば検証」と柔軟に制御できる

ただしnull値の扱いには注意が必要です。null前提のコードでnullチェックを怠ると、実行時にNull Pointer的なエラー(Attempt to read property on nullなど)を招くことがあります。nullを許可する項目では、参照側でも常にnullの可能性を考慮してください。

Migrationでのnullableの使い方

まずはデータベース側です。Laravelのマイグレーションでは、カラム定義に->nullable()をチェーンするだけで、その列にNULLを保存できるようになります。

新しいカラムをnullableで追加する基本例

もっとも基本的な形が$table->string('name')->nullable()です。以下はusersテーブルに、null許容のemailbirthdateを追加する例です。

<?php

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

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            // 文字列カラムをnull許容で追加する基本形
            $table->string('name')->nullable();
            $table->string('email')->nullable();
            // 日付カラムもnull許容にできる
            $table->date('birthdate')->nullable();
        });
    }

    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn(['name', 'email', 'birthdate']);
        });
    }
};

->nullable()を付けない場合、そのカラムはNOT NULL制約になり、null(値なし)で保存しようとするとデータベースエラーになります。「入力が任意な項目」にはnullable()を付けるのが基本です。マイグレーション自体のコマンド操作はPHP artisanコマンド活用法の記事で詳しく解説しています。

既存カラムをnullableに変更する場合

すでにあるカラムを後からnull許容へ変える場合は、->change()を使います。以下は、NOT NULLだったphoneカラムをnull許容に変更する例です。

public function up(): void
{
    Schema::table('users', function (Blueprint $table) {
        // 既存カラムをnull許容へ変更する
        $table->string('phone')->nullable()->change();
    });
}

変更時の注意点は次のとおりです。

  • 元の型を省略しないchange()は既存定義を上書きするため、string('phone')のように型・長さも含めて再指定します。nullable()だけを付け直そうとすると型が意図せず変わることがあります。
  • Laravel 10以降はdoctrine/dbal不要:Laravel 9以前でchange()を使うにはdoctrine/dbalパッケージが必要でしたが、Laravel 10以降は標準でchange()が使えます(利用中のバージョンはLaravelバージョン確認の記事で確認できます)。
  • NOT NULL → nullableは安全、逆は注意:null許容へ緩める方向は既存データを壊しませんが、nullableをNOT NULLへ戻す場合は、既存のnullレコードがあると変更に失敗します。事前にnullをデフォルト値で埋める必要があります。

ロールバック(down)も忘れずに、変更前の状態へ戻す処理を書いておきましょう。スキーマ変更を伴う設計変更の例は主キーをULIDに変更する記事も参考になります。

Validationでのnullableの使い方

次に入力チェック側です。フォームリクエストのバリデーションでnullableルールを指定すると、その項目が空(null)ならエラーにせず通し、値がある場合だけ他のルールを適用できます。

nullableルールの基本例

配列形式で書くと、'field' => ['nullable', 'string']のようになります。以下は任意項目を含むバリデーション例です。

$request->validate([
    'name'      => ['required', 'string', 'max:255'],
    'email'     => ['required', 'email', 'max:255', 'unique:users'],
    // 空ならスキップ、入力があれば数値として検証
    'phone'     => ['nullable', 'numeric'],
    // 空ならスキップ、入力があれば日付として検証
    'birthdate' => ['nullable', 'date'],
]);

phonebirthdateは、未入力(null)ならそのまま通過し、値が入っていればnumeric / dateのルールで検証されます。nullableを付けないと、Laravelは「入力があるべき」と解釈し、空でも型ルールでエラーになることがあるため、任意項目には明示的に付けるのが安全です。より発展的な検証はLaravelバリデーションをマスターする記事で解説しています。

nullable / required / sometimes / present の違い

nullableは似たルールと混同されがちです。「キーの有無」と「空を許すか」の2軸で整理すると分かりやすくなります。

ルール意味空(null)を許可キー自体が無い場合
nullable値がnullでも許可し、他ルールをスキップ許可する他ルール次第
required必須。null・空文字・空配列を拒否拒否するエラー
sometimesキーが存在する時だけ他ルールを適用—(存在時のみ検証)検証しない(許可)
presentキーの存在は必須。値は空でもよい許可するエラー
  • nullable vs required:任意ならnullable、必須ならrequired。真逆の関係です。
  • nullable vs presentpresentは「キーは必ず送ること。ただし中身は空でも可」。フォームで項目自体の送信を保証したい時に使います。
  • nullable vs sometimessometimesは「キーが無ければ検証しない」。部分更新(PATCH)で送られた項目だけ検証したい時に便利です。['sometimes', 'nullable', 'string']のように組み合わせられます。

空文字がnullへ変換されるケースに注意

LaravelにはConvertEmptyStringsToNullというミドルウェアが標準で有効になっており、リクエストの空文字("")は自動的にnullへ変換されます。HTMLフォームの未入力テキストは空文字で送られるため、実際にはnullとしてバリデーションに渡ります。

この挙動を知らないと、次のような食い違いが起きます。

  • フォームで空欄のまま送信 → 空文字 → nullに変換 → nullableならOK、requiredならエラー
  • DB側がnullable()なら空欄はnullで保存される。DBがNOT NULLだと、空文字ではなくnullが渡るため保存エラーになる

「空文字で保存されるはず」と思っていた項目がnullになるのはこのためです。Validationとカラム定義(NOT NULL / nullable)を揃えておけば、この食い違いは防げます。

実務でのnullable利用例

実際の開発では、次のような任意項目でnullableが役立ちます。いずれも「Migrationでnullable()」「Validationでnullable」をセットで揃えるのが基本です。

  • フォーム入力(任意項目):ミドルネーム、電話番号、備考欄など。例:['nullable', 'string', 'max:255']
  • 日付:退会日、公開予定日など未定になり得る項目。例:['nullable', 'date']。DB側は$table->date('published_at')->nullable()
  • 数値:割引率や在庫上限など未設定を許す項目。例:['nullable', 'integer', 'min:0']
  • 外部キー:「担当者未割り当て」など関連が任意なケース。例:$table->foreignId('user_id')->nullable()->constrained()とし、Validationは['nullable', 'exists:users,id']

特に外部キーをnullableにする場合は、リレーション先を参照するコードでnullチェックを入れておくと、担当者未割り当てのレコードでもエラーになりません。

まとめ

Laravelのnullableは、DB(Migration)とValidationの両方で「空を許可する」ための仕組みですが、扱う対象が異なる別々の設定です。

  • Migration$table->string('name')->nullable()でカラムにNULLを許可。既存カラムは->change()で変更できる。
  • Validation'field' => ['nullable', 'string']で空入力を許可。required / sometimes / presentとの違いを押さえる。
  • 空文字→null変換ConvertEmptyStringsToNullにより空欄はnull扱い。DBとValidationのnullable設定を揃えて食い違いを防ぐ。

「空を許可したい項目」は、MigrationとValidationの両方でnullableを揃える——これを意識するだけで、保存エラーや意図しないバリデーション失敗の多くを防げます。

関連記事

参考リンク

ホーム » 記事一覧 » .htaccess » Laravel nullableとは|MigrationとValidationでの使い方

投稿者

ここまで読んでいただき、ありがとうございます。

このサイトでは、私自身が関わっていることや、興味を持って試していることをそのまま置いています。

内容を見ていて、
「少し話を聞いてみたい」
「協業できる部分がありそう」
と感じる点があれば、下記のお問い合わせフォームからご連絡ください。状況を確認したうえで、必要な範囲でお返事します。

特に、以下のWordPressサイトに関する相談にも対応しているのでご興味ありましたらご相談ください。


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です