Laravel9の便利そうなクエリビルダをまとめました。
has
リレーション先にレコードがあるレコードのみ取得
// commentが少なくとも1つ以上あるすべてのpostを取得
$posts = Post::has('comments')->get();
whereRelation
リレーション先のテーブルでwhereをすることができます。
複数の条件を指定したい場合はwhereHas()
を使用します。
// users → companies.name === $name のユーザーのみ取得
$users = User::whereRelation('company', 'name', $name)->get();
orWhereRelation
orWhere
のRelation版です。
// users → companies.name === $name or companies.address === $address のユーザーのみ取得
$users = User::whereRelation('company', 'name', $name)
->orWhereRelation('company', 'address', $address)
->get();
whereHas
リレーション先のテーブルで、複数の条件を指定することができます。
// users → companies.name === $name and companies.address === $address のユーザーのみ取得
$users = User::whereHas('company', function ($query) use ($name, $address) {
$query->where('name', $name)
->where('address', $address);
})->get();
doesntHave
指定したリレーション先のレコードが存在しないレコードのみに絞り込むことができます。
条件を指定したい場合はwhereDoesntHave()
を使用します。
// 紐づくpostsのレコードがないユーザーのみを取得
$users = User::doesntHave('posts')->get();
whereDoesntHave
whereHasの逆で、不一致のレコードを取得します。
// 紐づくposts.title === $titleのレコードがないユーザーのみを取得
$users = User::whereDoesntHave('posts', function ($query) {
$query->where('title', $title);
})->get();
with
リレーション先のレコードを取得します。
AS
は使用できません。
// users → postsのデータが取得される
$users = User::with('posts')->get();
withのオプション
複数指定
// users → posts, users → companyのデータが取得される
$users = User::with(['posts', 'company'])->get();
取得するレコードの条件指定
// postsはapprovedがfalseのレコードのみ取得される
$users = User::with([
'company',
'posts' => function ($query) {
$query->where('approved', false);
}
])->get();
.(ドット)区切りで孫のレコードも取得
// users → posts → commentsのデータが取得される
$users = User::with('posts.comments')->get();
ネストした孫のレコードを複数取得
// users → posts → comments,detailsのデータが取得される
$users = User::with(
[
'posts' => [
'comments',
'details'
]
]
)->get();
:でselectをする
// postsはidとtitleしか取得されない
$users = User::with('posts:id,title')->get();
:でselectをする
// postsはidとtitleしか取得されない
$users = User::with('posts:id,title')->get();
withCount
リレーション先テーブルのレコード数を生成してくれます。
複数指定することも可能です。
// posts_countというプロパティ名で、postsのカウントが取得されます。
$users = User::withCount('posts')->get();
echo $users[0]->posts_count;
// posts_countとpending_posts_countが取得されます。
$users = User::withCount(
[
'posts',
'posts AS pending_posts_count' => function ($query) {
$query->where('approved', false);
}
]
)->get();
echo $users[0]->posts_count;
echo $users[0]->pending_posts_count;
常にwithロードするテーブルを指定
Modelの$withを指定することで、常にロードするテーブルを指定できます。
class User extends Model
{
/**
* 常にロードする必要があるリレーション
*
* @var array
*/
protected $with = ['permission'];
public function permission()
{
return $this->HasOne(Permission::class);
}
}
このようにして、$withから一時的に外すことが可能です。
$users = User::without('permission')->get();