Laravel 5.4 で追加された Higher Order Messages を使ってけっこう感動した。

https://laravel.com/docs/5.5/collections#method-flatmap

具体例で説明したい。

前提

CompanyUser というモデルがあるとする。

  • Company hasMany Users
  • User belongsTo Company

という関係。

Company モデルには

  • 契約期限が切れているかを判定する getIsContractExpiredAttribute
  • 契約期限が切れている企業の各社員にメールする notifyContractExpiration

というメソッドが生えている、とする。
(色々おかしいと思いますが、コレクションの説明のため)

で、 Company から契約期限が切れた企業をランダムに5件取得して、契約期限切れのメールを送りたい、となったとする。

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;

クロージャーが減ってめちゃくちゃ気持ち良い。

解説みたいな

上の例で 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みたいで楽しい。