前回は、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,
       },
     ],
   }

By khino