Laravelでリレーション先のそのまたリレーション先のデータを取得する2つの方法についてまとめます。
今回は例として、
というケースを考えます。
目次
データベース構造
記事用なので簡易的に書きます。
ユーザーテーブル(users)
カラム名 | データ内容 | FK |
---|---|---|
id | ID | |
name | 名前 | |
メールアドレス |
記事テーブル(articles)
カラム名 | データ内容 | FK |
---|---|---|
id | ID | |
user_id | 投稿ユーザーID | ◯ |
category_id | カテゴリーID | ◯ |
tile | 記事タイトル | |
body | 記事の内容 |
カテゴリーテーブル(categories)
カラム名 | データ内容 | FK |
---|---|---|
id | ID | |
name | 名前 |
モデルファイル
Laravel8だとapp/Models/◯◯.php
です。(Laravel8からModelsディレクトリが標準搭載されていますね)
ユーザーモデル
実際には現実的ではないですが、説明を簡略化するためにユーザーは1つの記事しか投稿できない(=ユーザーと記事が1対1の関係)前提とします。
public function article()
{
return $this->belongsTo(Article::class);
}
記事モデル
public function category()
{
return $this->belongsTo(Category::class);
}
リレーション先のリレーション先のデータを取得する2つの方法
ドット(.)で繋ぐ
モデルインスタンスを取得する際にwith()
の中でリレーションメソッドをドット(.
)繋ぎ(=文字列の連結)で記載する。(with()
はN+1問題対策用)
$user = User::with(['article.category'])->first();
// ユーザーが投稿した記事のカテゴリー名を取得
$user->article->category->name
Laravelではドット繋ぎで1つ先の階層にアクセス記法がいろいろなところで使われています。(以下のZennの記事も自分が書いたものなので近日ブログに移植します)
Laravelでは上記記事のようにセッションデータとか設定内容(config
ファイル)とかでドットが使われます。
クロージャを使う
with()
の中でクロージャを使う方法です。
$user = User::with(['article' => function ($query) {
$query->with(['category'])
}])->first();
// ユーザーが投稿した記事のカテゴリー名を取得
$user->article->category->name
最後に
クロージャを使った方法はリレーション先で検索することができるみたい(実際に試してない)なので、
単純にリレーション先のリレーション先のデータを取得したい場合は、ドット(.
)を使う方法の方がコード量も少なく見た目もスッキリして良いかなと思いました。
Laravel学習にオススメの書籍・教材はこちらにまとめていますので併せてご覧ください。
あわせて読みたい


【現役エンジニア厳選】Laravel学習にオススメの書籍・教材(レベル別)
プログラミング言語PHPのフレームワークであるLaravelを学習するための書籍・教材の中で、現役Laravelエンジニアの僕がオススメするものをご紹介します。 Laravelを勉強…
コメント