新しく追加されたクエリビルダーのsoleメソッドとは

#はじめに
Laravelのバージョンが**8.23**以上からクエリビルダーに`sole`メソッドが導入されています。
soleメソッドは**単一レコードに一致する場合のみ、一致したレコードを取得します。**一致しない場合は例外エラーが発生します。
この記事は簡単なデモを通じて下記内容について解説しています。

* soleメソッドの使い方について
* データ取得メソッドのfirst、get、soleの違いについて

#事前準備
予め`user`テーブルに次の値をセットしています。

```
+----+-------+--------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| id | name  | email              | email_verified_at | password                                                     | remember_token | created_at          | updated_at          |
+----+-------+--------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
|  1 | test1 | test1@example.com  | NULL              | $2y$10$9U3mn6osC2Xek9j1BvPV1OMoG2zVtNOG.Cikgg62UO/O2glF7q2Ky | NULL           | 2021-02-13 07:56:52 | 2021-02-13 07:56:52 |
|  2 | test2 | test2@example.com  | NULL              | $2y$10$.TYqe0M6q3feUwqSdrUFAO9XIG4ja4tQC6IDLkEy1DI23EXFPX7I6 | NULL           | 2021-02-13 07:57:15 | 2021-02-13 07:57:15 |
|  3 | test3 | test3@example.com  | NULL              | $2y$10$E7SPrfMjwyLFlP.7YB0Ak.DjO73IOdhjEQ375eEaEbcv140zPt63C | NULL           | 2021-02-13 07:57:47 | 2021-02-13 07:57:47 |
|  4 | test3 | test33@example.com | NULL              | $2y$10$DrKwopQ2ClXxLozoKD/yque2A20Hl4Bu.JRcb9nTvJTL0CEnOT8.O | NULL           | 2021-02-14 09:38:26 | 2021-02-14 09:38:26 |
+----+-------+--------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
4 rows in set (0.01 sec)
```

今回はtinkerを使用してsoleメソッドの挙動について確認していきたいと思います。
ちなみにtinkerの立ち上げは下記コマンドになります。

```
$ php artisan tinker
```


#soleメソッドの使い方
soleメソッドを使用するときのケースとして下記の3つが想定されます。

1. クエリに一致するレコードが**単一**の場合
2. クエリに一致するレコードが**ゼロ**の場合
3. クエリに一致するレコードが**複数**の場合

##クエリに一致するレコードが単一の場合

###getメソッドの場合

```
>>> $user = User::where('name', 'test1')->get();
=> Illuminate\Database\Eloquent\Collection {#3406
     all: [
       App\Models\User {#3410
         id: 1,
         name: "test1",
         email: "test1@example.com",
         email_verified_at: null,
         created_at: "2021-02-13 07:56:52",
         updated_at: "2021-02-13 07:56:52",
       },
     ],
   }
```

###firstメソッドの場合

```
>>> $user = User::where('name', 'test1')->first();
=> App\Models\User {#3399
     id: 1,
     name: "test1",
     email: "test1@example.com",
     email_verified_at: null,
     created_at: "2021-02-13 07:56:52",
     updated_at: "2021-02-13 07:56:52",
   }
```

###soleメソッドの場合

```
>>> $user = User::where('name', 'test1')->sole();
=> App\Models\User {#3410
     id: 1,
     name: "test1",
     email: "test1@example.com",
     email_verified_at: null,
     created_at: "2021-02-13 07:56:52",
     updated_at: "2021-02-13 07:56:52",
   }
```

##クエリに一致するレコードがゼロの場合

###getメソッドの場合

```
>>> $user = User::where('name', 'test1234')->get();
=> Illuminate\Database\Eloquent\Collection {#3408
     all: [],
   }
```

###firstメソッドの場合

```
>>> $user = User::where('name', 'test1234')->first();
=> null
```

###soleメソッドの場合

```
>>> $user = User::where('name', 'test1234')->sole();
Illuminate\Database\Eloquent\ModelNotFoundException with message 'No query results for model [App\Models\User].'
```

##クエリに一致するレコードが複数の場合

###getメソッドの場合

```
>>> $user = User::where('name', 'test3')->get();
=> Illuminate\Database\Eloquent\Collection {#4299
     all: [
       App\Models\User {#3399
         id: 3,
         name: "test3",
         email: "test3@example.com",
         email_verified_at: null,
         created_at: "2021-02-13 07:57:47",
         updated_at: "2021-02-13 07:57:47",
       },
       App\Models\User {#3403
         id: 4,
         name: "test3",
         email: "test33@example.com",
         email_verified_at: null,
         created_at: "2021-02-14 09:38:26",
         updated_at: "2021-02-14 09:38:26",
       },
     ],
   }
```

###firstメソッドの場合

```
>>> $user = User::where('name', 'test3')->first();
=> App\Models\User {#3404
     id: 3,
     name: "test3",
     email: "test3@example.com",
     email_verified_at: null,
     created_at: "2021-02-13 07:57:47",
     updated_at: "2021-02-13 07:57:47",
   }
```

###soleメソッドの場合

```
>>> $user = User::where('name', 'test3')->sole();
Illuminate\Database\MultipleRecordsFoundException
```

#まとめ
デモを通してsoleメソッドの使用ケースは
**単一のレコードの取得が必要で、かつ必ず単一レコードのみが存在することを保証されている**ときだと思いました。

#参考
[Understanding the sole() Query Builder Method](https://laravel-news.com/understanding-the-sole-query-builder-method)