前回は、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,
},
],
}
メルマガ購読の申し込みはこちらから。
