0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

qnoteAdvent Calendar 2024

Day 23

Laravel eloquentのwith・loadでの特定カラム取得時のTIPS

Posted at

概要

LaravelのEloquentにて利用できるwithとloadメソッドですが、
特定のカラムだけを取得したい時に、その手法や気をつけて欲しいことなどを下記2つTIPSとして紹介します。

  1. 連続したリレーション先でも特定カラムを取得したい場合
  2. クロージャを使いつつ特定カラムを取得したい場合

※例として、すべてwithを使ってコードを載せていますが、同様の内容をloadでも利用可能です。
※「Laravel9以降」「php8以降」を前提としてコードを記載しています。

前提知識

通常、withloadで必要な特定カラムを取得したい場合、
下記のように、リレーション名(postsなど)のあとに:をつけて必要なカラム名(id,user_id,titleなど)を記載すればOKです。

User::with('posts:id,user_id,title')->get();

1. 連続したリレーション先でも特定カラムを取得したい場合

基本的にドット記法で連続したリレーションを記載しつつ、:で必要なカラムを記載すればOKです。

// postsに紐づいたcommentsも一緒に取得&カラムを絞りたい場合
User::with([
    'posts:id,user_id,title',
    'posts.comments:id,post_id,content',
)->get();

特定の時だけ連続したリレーション(posts.commentsなど)を取得したい、かつ、whenを使って、それを表現したい場合は、whenを書く場所に要注意です。(下記)

NGパターン
whenwithの後に記載

User::with('posts:id,user_id,title')
    ->when($condition, fn ($q) => $q->with('posts.comments:id,post_id,content'))
    ->get();

こう書くと、with('posts:id,user_id,title')の方のカラム制限が外れてしまい
with('posts')と書いたのと同じように動いてしまいます。
(commentsの方のカラム制限=with('posts.comments:id,post_id,content')は機能します。)


OKパターン
whenwithの前に記載

User::when($condition, fn ($q) => $q->with('posts.comments:id,post_id,content'))
    ->with('posts:id,user_id,title')
    ->get();

こう書くと、postsposts.cooments、どちらも特定のカラムだけ取得できます。

意外と気付きにくいので、お気をつけください。

2. クロージャを使いつつ特定カラムを取得したい場合

with内でクロージャを使いたい場合は、:を使った書き方ができません。

// NG(エラー発生)
User::with(['posts:id,user_id,title' => fn ($q) => $q->latest()])->get();


そのため、クロージャ内でselectを使って絞りましょう。

// OK
User::with(['posts' => fn ($q) => $q->select(['id', 'user_id', 'title'])->latest()])->get();

select内でカラムを絞る場合、リレーション元と先で、同じ名前のカラム名が存在する場合は、テーブル名を明示する必要があります。(下記)

// usersテーブルにも「id」、postsテーブルにも「id」カラムが存在する場合、'posts.id'と明示が必要
User::with(['posts' => fn ($q) => $q->select(['posts.id', 'user_id', 'title'])->latest()])->get();

終わりに

必要なカラムだけ取得する癖をつけると、プロダクトが拡大してDBテーブルにカラムを追加した場合などでもPFMの低下を抑えることができます。
普段から必要なカラムだけ取得するよう心がけていきたいですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?