Laravel 8で foreignIdFor() メソッドが導入されました。
外部キーカラムの定義がよりシンプルで安全になる機能です。
foreignIdFor() とは
foreignIdFor() は、モデルクラスから外部キーカラムを自動生成するメソッドです。
Before: 従来の書き方
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
After: foreignIdFor() を使った書き方
$table->foreignIdFor(User::class)
->constrained()
->onDelete('cascade');
わずか1行で、カラムの作成から外部キー制約の設定まで完結します。
constrained() メソッドについて
constrained() は外部キー制約を自動的に設定するメソッドです。
$table->foreignIdFor(User::class)->constrained();
このコードは以下を自動的に行います:
– モデルクラスから参照先のテーブル名を推測(User → users)
– 主キーカラム id への参照を作成
– 外部キー制約を設定
constrained() を呼ばなければ、カラムのみが作成され、外部キー制約は設定されません。
// カラムのみ作成(制約なし)
$table->foreignIdFor(User::class);
// カラム + インデックスのみ(制約なし)
$table->foreignIdFor(User::class)->index();
主なメリット
1. 型の安全性が向上
参照先のテーブルの主キー型と自動的に一致します。
users.id が bigInteger なら、外部キーも unsignedBigInteger として作成されます。
2. タイプミスを防止
// モデルクラスから自動生成されるため、タイプミスが起きない
$table->foreignIdFor(User::class); // → user_id
// 従来の方法だとタイプミスのリスク
$table->unsignedBigInteger('usr_id'); // うっかりミス
3. コードの意図が明確
一目で「これは User モデルへの外部キーだ」と分かります。
注意点
モデルクラスが必要
当然ですが、モデルクラスが存在しないと使えません。
// モデルがない外部サービスのテーブルなど
$table->unsignedBigInteger('external_service_id');
カスタムテーブル名に注意
モデル名とテーブル名が規則通りでない場合は、明示的に指定が必要です。
class Person extends Model {
protected $table = 'users';
}
// persons テーブルを探してしまうため、明示的に指定
$table->foreignIdFor(Person::class)->constrained('users');
カラム名のカスタマイズ
デフォルトでは {model}_id という名前になります。
カスタマイズする場合は第2引数を使います。
$table->foreignIdFor(User::class, 'author_id')->constrained('users');
複合主キーには非対応
複合主キーへの参照には従来の方法を使う必要があります。
よく使うパターン
// nullable な外部キー
$table->foreignIdFor(User::class)->nullable()->constrained();
// カスケード削除
$table->foreignIdFor(User::class)
->constrained()
->onDelete('cascade');
// SET NULL
$table->foreignIdFor(User::class)
->nullable()
->constrained()
->onDelete('set null');
// インデックスのみ(外部キー制約なし)
$table->foreignIdFor(User::class)->index();
まとめ
foreignIdFor() は、外部キー定義をより安全で保守しやすくする優れた機能です。
特別な理由がない限り、Laravel 8以降のプロジェクトでは積極的に使用することをお勧めします。