カスタムピボットモデルとは
belongsToMany(多対多)の中間テーブルは、デフォルトでは素のIlluminate\Database\Eloquent\Relations\Pivot インスタンスとして扱われます。中間テーブルに追加のカラム(承認日時、ロールの種類など)を持たせたり、アクセサ・ミューテタ・独自メソッドを追加したりしたい場合は、Pivot を継承したカスタムモデルを作成します。
belongsToMany の定義で using() を呼び出し、このカスタムモデルを使うようリレーションに伝えます。
カスタムピボットモデルを保存するときは、モデル名を必ずアルファベット順の単数形で命名してください(
RoleUser であって UserRole ではありません)。ただしこれは表示名の慣習であり、実際のクラス名は自由に決められます。as()で取得したい属性を指定する
デフォルトでは中間テーブルの値は pivot プロパティ経由でアクセスします。as() メソッドを使うと、この名前を変更できます。
追加カラムとタイムスタンプ
中間テーブルにapproved のような追加カラムがある場合は withPivot() で明示的に取得対象に含めます。created_at / updated_at を管理する場合は withTimestamps() を呼び出します。
ピボットモデルからの逆参照
カスタムピボットモデルには、宣言元モデル・関連先モデルへのbelongsTo リレーションを自由に定義できます。
$roleUser->role や $roleUser->user で関連モデルにアクセスできます。ただし、これらのリレーションを親クエリ実行時に自動的にEagerロードしたい場合は、以下の chaperone() を使う方法があります。
chaperone()による自動Eagerロード(Laravel 13)
Laravel 13で、ピボットモデルに定義した role() / user() のような belongsTo リレーションを、belongsToMany クエリの実行時に自動でハイドレート(Eagerロード相当の紐付け)できる chaperone() メソッドが追加されました。
chaperone() を呼び出すと、Eloquentはピボットモデル(RoleUser)が持つ belongsTo リレーションの名前を自動的に推測し、Role::with('users') のようにコレクションを取得した際、各ピボットに紐づく宣言元モデル・関連先モデルへの参照を追加のクエリなしで設定します。
非標準なリレーション名を使う場合
ピボットモデルのbelongsTo リレーションのメソッド名が標準的な命名(宣言元・関連先モデル名のキャメルケース単数形)と異なる場合は、chaperone() の引数で明示的に指定します。
次のステップ
リレーションシップ
belongsToManyを含む基本的なリレーションの定義方法に戻って復習します。
Eloquent Observers とモデルイベント
モデルイベントを使ってピボットモデルの保存・更新をフックする方法を学びます。