【Laravel】リレーション先のリレーション先のデータを取得する2つの方法

  • URLをコピーしました!

Laravelでリレーション先のそのまたリレーション先のデータを取得する2つの方法についてまとめます。

今回は例として、

あるユーザーが投稿した記事のカテゴリーの名前を取得する

というケースを考えます。

※タイトルの「データ」はLaravelのEloquent(ORM)を使うので、モデルインスタンスを指します。

目次

データベース構造

記事用なので簡易的に書きます。

ユーザーテーブル(users)

カラム名データ内容FK
idID
name名前
emailメールアドレス
usersテーブル

記事テーブル(articles)

カラム名データ内容FK
idID
user_id投稿ユーザーID
category_idカテゴリーID
tile記事タイトル
body記事の内容
articlesテーブル

カテゴリーテーブル(categories)

カラム名データ内容FK
idID
name名前
categoriesテーブル

モデルファイル

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学習にオススメの書籍・教材はこちらにまとめていますので併せてご覧ください。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

ブログを開設するなら「SWELL」が絶対オススメ!

コメント

コメントする

目次