なぜこの記事を書こうと思ったのか
Laravelの公式ドキュメントには、一方向におけるリレーションしか記述されてなかった。
そのため、備忘録としてこの記事を書こうと思った。
本題
公式ドキュメントに書いてある例を引用して、解説する。
リレーション(Has One Through)
使用するテーブル
テーブル
mechanics
id - integer
name - string
cars
id - integer
model - string
mechanic_id - integer
owners
id - integer
name - string
car_id - integer
mechanics
→cars
→owners
って感じかな。
mechanicから見たとownerとのリレーション
リレーション(Mechanic.php)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
class Mechanic extends Model
{
/**
* 車の所有者を取得
*
* @return HasOneThrough
*/
public function carOwner(): HasOneThrough
{
return $this->hasOneThrough(
Owner::class, // 最終モデル
Car::class, // 中間モデル
'mechanic_id', // 中間モデルの外部キー
'car_id', // 最終モデルの外部キー
'id', // このモデルの主キー
'id', // 中間モデルの主キー
);
}
}
ここまでは公式ドキュメントに書いてある。
ownerから見たとmechanicとのリレーション
ここからは公式ドキュメントには書いていない。
リレーション(Owner.php)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
class Owner extends Model
{
/**
* 車の所有者を取得
*
* @return HasOneThrough
*/
public function carMechanic(): HasOneThrough
{
return $this->hasOneThrough(
Mechanic::class, // 最終モデル
Car::class, // 中間モデル
'id', // 中間モデルの主キー
'id', // 最終モデルの主キー
'car_id', // このモデルの外部キー
'mechanic_id', // 中間モデルの外部キー
);
}
}
hasOneThrough関数の引数について(まとめ)
- 第1引数:最終モデル
- 第2引数:中間モデル
- 第3引数:このモデルと結びつく中間モデルのキー
- 第4引数:中間モデルと結びつく最終モデルのキー
- 第5引数:第3引数と結びつくこのモデルのキー
- 第6引数:第4引数と結びつく中間モデルのキー
たぶんね😇