初めてのLARAVEL 5.6 : (31) RELATIONSHIPSで、Userモデルと Articleモデルを関連付けするのに少し詰まったのでメモ。
外部キー自体の知識については外部キーについて(MySQL編)この記事が分かりやすかった。
Userモデルの初期状態は、
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
Articleモデルの初期状態は、
$table->bigIncrements('id');
$table->string('title');
$table->text('body');
$table->timestamps();
User : Article = 1 : n の関連付けをするので、UserはArticleをたくさん持つ(hasMany)、Articleは1人のUserに帰属する(belongsTo)である。
public function user(){
return $this->belongsTo('App\User');
}
public function articles()
{
return $this->hasMany('App\Article');
}
Userモデルと Articleモデルを関連付けるため、Articleモデルに user_id を追加し、Userモデルの id と紐づける。
また、紐づけられたUserモデルのデータが削除されたら、紐づいているArticleモデルのデータも削除するようにする。
$table->bigIncrements('id');
$table->unsignedInteger('user_id'); //追加
$table->string('title');
$table->text('body');
$table->timestamps();
$table->foreign('user_id') //外部キーの宣言
->references('id') //参照先
->on('users') //参照テーブル
->onDelete('cascade'); //参照テーブルカラムが消えたら同時に消す
DBを全てロールバックし、再度全マイグレーションを実行するため、php artisan migrate:refreshを実行。
よく見てみると、紐づけられているUserモデルのidの型はbigIncrements、紐づけるために追加したArticleモデルのuser_idの型はunsignedIntegerとなっており、型が違う。
- bigIncrements => BIGINTを使用した自動増分(INCREMENT) ID
- unsignedInteger => 符号なし(UNSIGED)のINTを使用したID
よって、Articleモデルのuser_idの型をunsignedBigIntegerにすると良い。
migrateする際は、テーブルを捨てて作り直したいので、 php artisan migrate:freshを実行する。
符号なし(UNSIGNED)との型の整合性が気になるが、自動増分(INCREMENT)はもともと符号なしだから不整合は起きない!!
初めてのLARAVEL 5.6 は laravel6に対応しておらず、laravel6のUserモデルのidがbigintになっていたからこの問題が起こったのだろうーーー。
