2
4

Laravel9時点で使える Eloquent 便利そうなクエリビルダ

Last updated at Posted at 2023-11-22

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();
2
4
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
2
4