外部キーの準備
通常、外部キーは相手方テーブルで自動連番として生成されたキーを対象とすることが多い。
例えば参照先のテーブルのプライマリーキーが'id'であるとして、これがAuto Incrementの場合にはマイグレーションファイルでは以下のように定義される。
$table->bigIncrements('id');
これにより生成されるカラムのデータ型はunsignedBigIntegerとなるので、参照元のテーブルで外部キーを設定するときは以下のように定義する。
$table->unsignedBigInteger('参照先テーブル名の単数形_id');
例えば参照先テーブルをcustomersとすると、マイグレーションファイルでは以下のように書かれる。
| 1 2 3 4 5 6 7 8 9 10 11 | class CreateCustomersTable extends Migration {     public function up()     {         Schema::create('customers', function (Blueprint $table) {             $table->bigIncrements('id');             ........         });     }     ........ } | 
ordersテーブルから上記のcustomersテーブルを参照する場合、ordersテーブルの外部キーは以下のように記述する。
| 1 2 3 4 5 6 7 8 9 10 11 12 | class CreateOrdersTable extends Migration {     public function up()     {         Schema::create('orders', function (Blueprint $table) {             $table->bigIncrements('id');             $table->unsignedBigInteger('customer_id');             ........         });     }     ........ } | 
外部キーの設定
Laravelのモデルに外部キーを設定する場合、マイグレーションファイルでforeign()メソッドを使う。
具体的には、テーブルを作成するクラスのup()メソッドで呼ばれるSchema::create()メソッド内に以下を記述。
$table->foreign('外部キー')->references('参照キー')->on('参照テーブル');
外部キー制約
マイグレーションファイルで外部キーを設定した場合、デフォルトの外部キー制約はRESTRICTになる。この制約をCASCADEやSET NULLに変更することができる。
削除、更新に対する制約はonDelete()、onUpdate()をメソッドチェーンに追加して設定する。
| 1 2 | $table->foreign('外部キー')->references('参照キー')->on('参照テーブル') ->onDelete('CASCADE')->onUpdate('CASCADE'); | 
引数は大文字でも小文字でもよく、CASCADE、SET NULL、RESTRICTの何れかを指定する。
コード例
たとえば.投稿記事のPostモデルのテーブルがuser_idカラムを持ち、ここにUsersモデルのidを外部キーとする場合、PostのマイグレーションファイルのCreatePostsTableクラスのup()メソッドに、外部キー設定の行を記述する。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class CreatePostsTable extends Migration {     public function up()     {         Schema::create('posts', function (Blueprint $table) {             $table->bigIncrements('id');             // ユーザーIDの外部キー             $table->unsignedBigInteger('user_id');             ........             $table->foreign('user_id')->references('id')->on('users')             ->onUpdate('cascade')             ->onDelete('cascade');         });     }     ........ } |