LaravelでManyToMany(多対多リレーション)するときの注意点。

Laravel 8.xの話*1

readouble.com

上記ページのテーブル構造を例にとると、users.idとroles.idそれぞれをUUIDなどのinteger以外の主キーにすると、中間テーブルにデータを登録するときに片方のidが0になる現象が発生する。

例えばUserに対して複数のRoleをアタッチや同期した場合、role_user.user_idが0になると思われる。*2

これを回避する方法は、0になってしまうモデルに以下のコードを追加することだ。

public $incrementing = false;
protected $primaryKey = 'id';
protected $keyType = 'string';

こうすることで、UserおよびRoleそれぞれで採番したUUIDを使って中間テーブルを登録するようになる。 

以下、ヒントになった情報。

github.com

追記

ドキュメントを調べてみたら、下記のページに主キーを整数以外にした場合の注意点が記載してあった。

readouble.com

このページに、以下の記載がある。

 Eloquentは、主キーが増分整数値であることも想定しています。これは、Eloquentが主キーを自動的に整数にキャストすることを意味します。非インクリメントまたは非数値の主キーを使用する場合は、モデルにpublicの$incrementingプロパティを定義し、falseをセットする必要があります。

 

 モデルの主キーが整数でない場合は、モデルにprotectedな$keyTypeプロパティを定義する必要があります。このプロパティの値はstringにする必要があります。

そういうわけで、 主キーを文字型にするようなときは、$incrementingと$keyTypeを指定しなくてはいけないようだ。

*1:他のバージョンでも同様と思う

*2:試していないので、もしかしたらrole_idが0になるのかもしれない