Laravel 5.4 で追加された Higher Order Messages を使ってけっこう感動した。
Laravelのコレクションに対して、クロージャーを使わずに様々な処理を行えるもの。
具体例で説明したい。
前提
Company
と User
というモデルがあるとする。
- Company hasMany Users
- User belongsTo Company
という関係。
Company
モデルには
- 契約期限が切れているかを判定する
getIsContractExpiredAttribute
- 契約期限が切れている企業の各社員にメールする
notifyContractExpiration
というメソッドが生えている、とする。で、
- 契約期限が切れた
Company
をランダムに5件取得 - その
Company
の社員に対して、契約期限切れのメールを送りたい
となったとする。
(色々おかしいと思いますが、コレクションの説明のため)
Before (~ 5.3)
Company::with('users')
->all()
->filter(function ($company) {
return $company->isContractExpired;
})
->take(5)
->pluck('users')->flatten()
->each(function ($user) {
$user->notifyContractExpiration();
});
After (5.4 ~)
Company::with('users')
->all()
->filter->isContractExpired
->take(5)
->flatMap->users
->each->notifyContractExpiration();
クロージャーが減ってめちゃくちゃ気持ち良い。
また、後者ではしれっと flatMap
も使っている。これも便利。
ちょっと解説
上の例で Company::all()->map
とすると、 Illuminate\Support\HigherOrderCollectionProxy
というものが返ってきて、これが色々やってくれるっぽい。
この機能が使えるメソッドは以下の通り。
- average
- avg
- contains
- each
- every
- filter
- first
- flatMap
- map
- partition
- reject
- sortBy
- sortByDesc
- sum
上記の例で、例えば Company::all()->sum->isContractExpired
とすると、契約期限が切れた企業の総数が返ってくる。
SQLみたいで楽しい。