with&whereでリレーショナルデータにも条件をつけてデータを取得する(Laravel)

1 min read読了の目安(約800字

Laravelでリレーショナルデータも一緒に取得したいとなった場合に、withメソッドを使用することがあると思いますが、withメソッドだけを使用するとリレーショナルデータを無条件に全て取得します。

例えばZennのような記事投稿サービスを開発しているとして、 Laravelというタグがついている記事だけを取得したいとします。

テーブル定義は仮にこのようにします。 articles テーブルと tags テーブルがあり1対多の関係になっています。

articles
  - id
  - author_id
  - title
  - content
  - created_at
  - updated_at
  
tags
  - article_id
  - name

タグ名がLaravelの記事だけを一覧で取得する

リレーショナルデータに条件をつけて一覧取得したい場合は、withメソッドとwhereメソッドを使用します。

$tagName = 'Laravel';

$articles = Article::with(['tags' => function($query) use ($tagName) {
    $query->where('name', $tagName);
}])->get();

このようにwithメソッドに対して、コールバック関数を指定することでリレーショナルデータに条件をつけて取得することができます。

おわりに

リレーショナルデータに条件をつけて取得したいケースが個人的に最近多くて結構この構文を使っているので、使いこなせると実装の幅が広がるなと思いました。

withメソッドはeager Loadingといって、データベースアクセスのクエリを最低限に抑えて「N+1」問題を解決できるので、積極的に使っていくのが良いと思います。