前回は、1つの値を返すCollectionのメソッドを紹介しましたが、今度はCollectionを返すメソッドの紹介です。まさにこれが実践でよく使われるものです。
レコード
まずは、前回と同様に、以下の3レコードのみがusersのDBテーブルに存在するとの仮定です。
mysql> select id, name, birth_date from users; +----+---------------+------------+ | id | name | birth_date | +----+---------------+------------+ | 1 | 坂本 充 | 1997-03-02 | | 2 | 藤本 和也 | 2005-10-03 | | 3 | 近藤 知実 | 1972-09-14 | +----+---------------+------------+ 3 rows in set (0.00 sec)
指定した項目値の抽出
pluck()
このメソッドは、引数として与えた項目名の値をCollectionとして返します。
>>> User::all()->pluck('birth_date') => Illuminate\Support\Collection {#3302 all: [ "1997-03-02", "2005-10-03", "1972-09-14", ], }
引数として2つの項目名を与えると、後者をキーとした連想配列のCollectionを返します。
>>> User::all()->pluck('name', 'id') => Illuminate\Support\Collection {#4258 all: [ 1 => "坂本 充", 2 => "藤本 和也", 3 => "近藤 知実", ], }
複数の項目値を抽出するには、
map()
を使用します。
>>> User::all()->map(function ($user) { return $user->only(['id', 'name', 'birth_date']); }) => Illuminate\Support\Collection {#4090 all: [ [ "id" => 1, "name" => "坂本 充", "birth_date" => "1997-03-02", ], [ "id" => 2, "name" => "藤本 和也", "birth_date" => "2005-10-03", ], [ "id" => 3, "name" => "近藤 知実", "birth_date" => "1972-09-14", ], ], }
条件に合うレコードを抽出
filter()
このメソッドは、Collectionから条件に合う必要なレコードだけを抽出します。
>>> User::all()->filter(function ($user) { return $user->birth_date < '1990-01-01'; }) => Illuminate\Database\Eloquent\Collection {#4025 all: [ 2 => App\User {#4179 id: 3, name: "近藤 知実", email: "atsushi.ito@example.net", email_verified_at: "2021-05-30 21:55:14", #password: "$2y$10$A7xldQvOiCfUOyNS57EEYu2/s77a70BPmGoOjzDSgTmveeRlcAD8.", #remember_token: "qOFWQFb5ER", birth_date: "1972-09-14", created_at: "2021-05-30 21:55:14", updated_at: "2021-05-30 21:55:14", }, ], }
条件を少し複雑にすると、
>>> User::all()->filter(function ($user) { if ($user->birth_date > '2000-01-01') return false; if ($user->birth_date < '1990-01-01') return false; return true; }) => Illuminate\Database\Eloquent\Collection {#4249 all: [ App\User {#4246 id: 1, name: "坂本 充", email: "nishida@example.net", email_verified_at: "2021-05-30 21:55:14", #password: "$2y$10$snEjTmJvBDu3uxd1bz0QDupihJA3zjvEH5J0pm/aLHG4UvpSfJe/q", #remember_token: "j8hPjp8ob7", birth_date: "1997-03-02", created_at: "2021-05-30 21:55:14", updated_at: "2021-05-30 21:55:14", }, ], }
というように、1990-01-01と2000-01-01の間に生まれたユーザーだけの取得も可能です。
ちなみに、reject()
はfilter()
の逆で、上と同じ結果が欲しいなら、以下のようtrue, falseがすべて逆になります。
>>> User::all()->reject(function ($user) { if ($user->birth_date > '2000-01-01') return true; if ($user->birth_date < '1990-01-01') return true; return false; })
それぞれのレコード(Userのオブジェクト)で属性処理
each()
このメソッドはまさに、よく使う以下のforeach()
の関数のようなもので取得したそれぞれのDBレコードにおいて、属性の処理が可能です。
foreach($rows as $row) { ... }
例えば、以下のようにUserのオブジェクトにageの属性を追加することができます。
>>> use Carbon\Carbon; >>> User::all()->each(function ($user) { $user->age = Carbon::parse($user->birth_date)->age; }) => Illuminate\Database\Eloquent\Collection {#3986 all: [ App\User {#4234 id: 1, name: "坂本 充", email: "nishida@example.net", email_verified_at: "2021-05-30 21:55:14", #password: "$2y$10$snEjTmJvBDu3uxd1bz0QDupihJA3zjvEH5J0pm/aLHG4UvpSfJe/q", #remember_token: "j8hPjp8ob7", birth_date: "1997-03-02", created_at: "2021-05-30 21:55:14", updated_at: "2021-05-30 21:55:14", age: 24, }, App\User {#4238 id: 2, name: "藤本 和也", email: "yoshida.kana@example.com", email_verified_at: "2021-05-30 21:55:14", #password: "$2y$10$QiozldxVUo3LLj347mqHxeoDh5TEcjddDwc6vN8Pv5b4kPgPUgjri", #remember_token: "frW94QFFZh", birth_date: "2005-10-03", created_at: "2021-05-30 21:55:14", updated_at: "2021-05-30 21:55:14", age: 15, }, App\User {#4180 id: 3, name: "近藤 知実", email: "atsushi.ito@example.net", email_verified_at: "2021-05-30 21:55:14", #password: "$2y$10$A7xldQvOiCfUOyNS57EEYu2/s77a70BPmGoOjzDSgTmveeRlcAD8.", #remember_token: "qOFWQFb5ER", birth_date: "1972-09-14", created_at: "2021-05-30 21:55:14", updated_at: "2021-05-30 21:55:14", age: 48, }, ], }メルマガ購読の申し込みはこちらから。