【Laravel】クエリビルダ/whereIn/whereHasを使った情報取得

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## リレーション先の条件での絞り込み

organization -> user -> post
(->は1対多の関係)

同じ```organization```に所属する```user```の```post```一覧を最新順に表示したい。

### 書き方①

```php
$orgUsersIds = User::where('organization_id', $user->organization_id)
                        ->with('organization')
                        ->pluck('id')
                        ->toArray();
Post::whereIn('user_id', $orgUsersIds)
       ->latest();
       ->paginate(25);
```

```SQL
 array:3 [
  0 => array:3 [
    "query" => "select `id` from `users` where `organization_id` = ?"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 1.44
  ]
  1 => array:3 [
    "query" => "select count(*) as aggregate from `posts` where `user_id` in (?, ?)"
    "bindings" => array:2 [
      0 => 1
      1 => 2
    ]
    "time" => 1.31
  ]
  2 => array:3 [
    "query" => "select * from `posts` where `user_id` in (?, ?) order by `created_at` desc limit 25 offset 0"
    "bindings" => array:2 [
      0 => 1
      1 => 2
    ]
    "time" => 1.43
  ]
]
```

### 書き方②
DBクエリビルダ的に書くと
```php
Post::select('posts.*')
      ->join('users', 'posts.user_id', 'users.id')
      ->where('users.organization_id', $user->organization_id)
      ->latest('posts.created_at')
      ->paginate(25);
```

```SQL
array:2 [
  0 => array:3 [
    "query" => "select count(*) as aggregate from `posts` inner join `users` on `posts`.`user_id` = `users`.`id` where `users`.`organization_id` = ?"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 2.11
  ]
  1 => array:3 [
    "query" => "select `posts`.* from `posts` inner join `users` on `posts`.`user_id` = `users`.`id` where `users`.`organization_id` = ? order by `posts`.`created_at` desc limit 25 offset 0"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 2.55
  ]
]
```

### 書き方③

```whereHas```を使うと遅くなるらしいがテストの実行時間は他と変わらなかった。

```php
Post::whereHas('user', function (Builder $query) use ($user) {
      $query->where('organization_id', $user->organization_id);
})->latest()->paginate(25);
```

```SQL
 array:2 [
  0 => array:3 [
    "query" => "select count(*) as aggregate from `posts` where exists (select * from `users` where `posts`.`user_id` = `users`.`id` and `organization_id` = ?)"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 1.41
  ]
  1 => array:3 [
    "query" => "select * from `posts` where exists (select * from `users` where `posts`.`user_id` = `users`.`id` and `organization_id` = ?) order by `created_at` desc limit 25 offset 0"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 1.3
  ]
]
```

https://readouble.com/laravel/9.x/ja/eloquent-relationships.html?header=%25E3%2583%25AA%25E3%2583%25AC%25E3%2583%25BC%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%25B3%25E3%2581%25AE%25E5%25AD%2598%25E5%259C%25A8%25E3%2581%25AE%25E3%2582%25AF%25E3%2582%25A8%25E3%2583%25AA

### 書き方④
書き方③の```whereHas```は遅いから代わりに```whereIn```を使うといいという記事をいくつも見た。

```php
Post::whereIn('user_id', function ($query) use ($user) {
      $query->from('users')
            ->select('users.id')
            ->where('users.organization_id', $user->organization_id);
})->latest()->paginate(25);
```

```SQL
 array:2 [
  0 => array:3 [
    "query" => "select count(*) as aggregate from `posts` where `user_id` in (select `users`.`id` from `users` where `users`.`organization_id` = ?)"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 1.67
  ]
  1 => array:3 [
    "query" => "select * from `posts` where `user_id` in (select `users`.`id` from `users` where `users`.`organization_id` = ?) order by `created_at` desc limit 25 offset 0"
    "bindings" => array:1 [
      0 => 1
    ]
    "time" => 1.33
  ]
]
```

https://github.com/laravel/framework/issues/18415#issuecomment-371662299