LaravelのEloquentにおける「hasManyThrough」リレーションは、「中間テーブル」を経由して別のテーブルに関連付けられたレコードを取得するための関係を表します。2つのテーブルをつなぐ中間テーブルを経由して、多対多のような関係を簡単に操作できます。
具体的な例を用いて説明します。
例: 国 -> ユーザー -> 投稿
考えられる3つのテーブルがあります:
countries
(国)users
(ユーザー)posts
(投稿)
各テーブルは次のように関連付けられています:
- 1つの国は複数のユーザーを持つことができる(
hasMany
関係)。 - 1人のユーザーは複数の投稿を持つことができる(
hasMany
関係)。
この場合、国から直接投稿を取得するためにhasManyThrough
を使用できます。つまり、国を起点として、ユーザーを経由して投稿にアクセスします。
実装例
// Countryモデル
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(
Post::class, // 最終的に取得したいモデル
User::class, // 中間モデル
'country_id', // 中間モデルの外部キー (usersテーブルに存在する)
'user_id', // 最終的なモデルの外部キー (postsテーブルに存在する)
'id', // ローカルキー (countriesテーブルの主キー)
'id' // 中間テーブルのローカルキー (usersテーブルの主キー)
);
}
}
引数の説明
- 第一引数:最終的に関連付けられているモデル名 (
Post::class
) - 第二引数:中間モデル名 (
User::class
) - 第三引数:中間モデル (
users
テーブル) が参照する外部キー (country_id
) - 第四引数:最終的なモデル (
posts
テーブル) が参照する外部キー (user_id
) - 第五引数:ローカルキー (デフォルトは
id
) - 第六引数:中間モデルのローカルキー (デフォルトは
id
)
使用例
Country
モデルのインスタンスから、関連するすべての投稿を取得できます。
$country = Country::find(1);
$posts = $country->posts; // この国に関連するすべての投稿を取得
このように、hasManyThrough
を使うと、中間テーブルを経由して簡単にリレーションを設定し、データを取得できます。