ネストしたwithでリレーション先の情報取得するカラムを指定する方法


Laravelが提供するリレーションでは、withメソッドを使うことでJOINを使うことなく関係するテーブルに情報を取得できます。

withの基本の使い方

// 商品情報を出品ユーザー情報と一緒に取得する
$products = Product::with('user');

withでのカラム指定

withを使う時は、.の後にカラムを記述することで、取得するカラムだけを指定することができます。
うっかり出品者のメアドやパスワードもレスポンスに含めてしまわないようにするためにも基本設定した方がいいですね。
(画面に表示してなくても、デベロッパーツールでレスポンスの見方を知ってる人には筒抜け)

// 商品情報を出品ユーザー情報(名前のみ)を取得する
// リレーション参照のために、参照カラム(idやproduct_idなど)を含める必要あり
$products = Product::with('user.id,name');

withでネストリレーション

商品情報とユーザー情報、さらにユーザーの画像情報(正規化して別テーブルに保存されている)と一緒に取得したい時は、ネストしたリレーションで取得することができます。

公式リファレンス:ネストしたEagerロード

// 商品情報を出品ユーザー情報と一緒に取得する
$products = Product::with('user.image');

ネストされたwithを使いつつ、参照カラムを指定する

・カテゴリーをメインに商品情報を参照
・さらに商品の出品者情報(usersテーブル)も参照したい
・usersテーブルにはemailなどのプライベートな情報があるので、カラム指定で取得するようにしたい

このパターンでは下記のように書く必要があります。

// OK
$categories = Category::with('products', function($products) {
    // ユーザーの画像URLを取得
    $products->with('user:id,name');
});

*ちゃんと確認してはいませんが、少なくとも5.8系以降では使用可能

ちなみに、↓のように書くとエラーになります。

// NG
$categories = Category::with('product.user:id,name');

withは便利ですが、不要なカラムは参照しないというセオリーを忘れずに使っていかなきゃですね!