【Laravel】Collectionにsoleメソッドが追加されたので使ってみた
こんにちは。
ニシザワです。
Laravel9が迫ってますね
Laravel8のマイナーバージョンアップでも知らないうちにいろいろな機能が追加されていたりします。
今回はそのうちの一つを紹介
Collectionでのsoleは条件に当てはまるものが1つだけの場合値を返してくれるメソッドです。
BuilderクラスのsoleはLaravel8で実装されています。(参考)
第一引数はcallableの指定が可能となっています。
keyがvalueと等しいもの等を検索し、一つだけの場合結果を返してくれます。
それ以外の場合は
結果がない場合は\Illuminate\Support\ItemNotFoundExceptionを投げます。
結果が複数の場合は\Illuminate\Support\MultipleItemsFoundExceptionを投げます。
ニシザワです。
Laravel9が迫ってますね
Laravel8のマイナーバージョンアップでも知らないうちにいろいろな機能が追加されていたりします。
今回はそのうちの一つを紹介
soleとは
soleは唯一の、たった一つのという意味がありCollectionでのsoleは条件に当てはまるものが1つだけの場合値を返してくれるメソッドです。
BuilderクラスのsoleはLaravel8で実装されています。(参考)
soleメソッドの内容
/**
* Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
*
* @param (callable(TValue, TKey): bool)|string $key
* @param mixed $operator
* @param mixed $value
* @return TValue
*
* @throws \Illuminate\Support\ItemNotFoundException
* @throws \Illuminate\Support\MultipleItemsFoundException
*/
public function sole($key = null, $operator = null, $value = null);
soleメソッドのinterfaceを見ていきましょう。第一引数はcallableの指定が可能となっています。
keyがvalueと等しいもの等を検索し、一つだけの場合結果を返してくれます。
それ以外の場合は
結果がない場合は\Illuminate\Support\ItemNotFoundExceptionを投げます。
結果が複数の場合は\Illuminate\Support\MultipleItemsFoundExceptionを投げます。
使い方
予めusersテーブルに値を用意しておきます。
+----+--------+--------------------+
| id | name | email |
+----+--------+--------------------+
| 1 | test | test@example.com |
| 2 | hoge | hoge@example.com |
| 3 | fuga | fufa@example.com |
| 4 | nextat | nextat@example.com |
| 5 | nextat | nextat2@example.com |
+----+--------+--------------------+
UserModelをCollectionに詰めておきます
$users = App\Models\User::all();
条件に当てはまるアイテムが1つの場合
$users->sole('email', 'nextat@example.com');
// または
$users->sole(function(App\Models\User $user): bool {
return $user->email === 'nextat@example.com'
});
// App\Models\User {
// id: 4,
// name: "nextat",
// email: "nextat@example.com",
// }
//
第2引数のオペレーターは省略可能です。
条件に当てはまるアイテムが2つ以上の場合
$users->sole('name', 'nextat');
// または
$users->sole(function(App\Models\User $user): bool {
return $user->name === 'nextat'
});
// \Illuminate\Support\MultipleItemsFoundException
条件に当てはまるアイテムがない場合
$users->sole('name', 'nextat2');
// または
$users->sole(function(App\Models\User $user): bool {
return $user->name === 'nextat2'
});
// \Illuminate\Support\ItemNotFoundException
今まで、唯一の要素を取得していた時は以下の様に場合分けしていたのではないでしょうか
$filteredUsers = $users->filter(
function(App\Models\User $user): bool {
return $user->name === 'nextat2'
});
if ($filteredUsers->count() > 1) {
throw new Illuminate\Support\MultipleItemsFoundException();
}
$user = $filteredUsers->first();
if ($user === null) {
throw new Illuminate\Support\ModelNotFoundException();
}
soleを使うと例外を投げてくれるので便利ですね。
参考にしてみてください。