0
0

【Laravel】with

Last updated at Posted at 2023-11-13

Laravel=5.6

withとは?

リレーションテーブルのデータを取得するための、Eloquentの記法。N+1問題を防止することができる。

使い方

Account.php
public function posts () {
    $this->hasMany('Post');
}
Account::with('posts')->get();

N+1問題とは?

アカウント数+1回のSQLが実行されるためパフォーマンスが悪い

$accounts = Account::get(); // Account::get()でSQL1回実行
foreach ($accounts as $key => $account) { 
    $accounts[key]->posts = $account->posts; // foreachの回数分SQL実行
}

様々な記法

2つ以上"先"のリレーション

Post.php
public function comments () {
    $this->hasMany('Comment');
}
Account::with('posts.comments')->get();

2つ以上のリレーション

Post.php
public function account () {
    $this->belongsTo('Account');
}
Post::with(['account', 'comments'])->get(); 

whereやorder by

アカウントデータをアカウント名昇順でソート
Account::with('posts.comments')->orderBy('name')->get();
コメントデータをコメント日時降順でソート
Account::with(['posts.comments' => function ($query) {
    $query->orderByDesc('created_at');
})->get();
投稿データを投稿日時でフィリタリングし、コメントデータも取得
Account::with('posts.comments')->with(['posts' => function($query){
    $query->where('created_at', '>', '2023-01-01 00:00:00');
}])->get();

whereHas

リレーション元のデータを、リレーション先のデータでフィルタリング

※withでは、リレーション元のデータをリレーション先のデータでソートやフィルタリングできない

アカウントデータをコメント日時でフィルタリング
Account::whereHas('posts.comments', function ($query) {
    $query->where('created_at', '>', '2023-01-01 00:00:00');
})->get();
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