エンジニアのひよこ_level10

毎日更新してた人。たまに記事書きます。

【Laravel6】Laravel6で追加されるLazyCollectionに思いを馳せてみる【678日目】

現状一つ悩みがありました

リポジトリパターンと呼ばれる、永続化したデータを取得・操作する際に、
Repositoryクラスに集約させるようなやり方があるのですが、

Eloquentのchunkメソッドを使って取得するときに、取得中に別な作業をさせようとすると、
Repositoryクラス内に、永続化とは違う動きをさせてしまう・・・

かといって、クエリビルダをサービスに渡すと、データの取得方法がEloquent限定、
Serviceが意識しないといけなくなる・・・

class UserRepository
{
    function getUser()
    {
        return User::select('user.*');
    }
}
class UserService
{
....

    function getCsv()
    {
        $query = $this->user_repository->getUser();
        $query->chunk(100, function ($users) use ($csv) {
             foreach ($users as $user) {
                   $this->setCsvData($csv, $user);
             }
        });
    }
}

ってなことを、日本語PHPユーザーズのSlackのLaravelチャンネルで相談してたら、いい感じに盛り上がった・・・

ら、面白いものがLaravel6に出るようで

LazyCollection

注意) ここからは、コード動かしてない、内部のコード読んで推測しているだけのお話です。

どうやら、cursor関数で取得したときに、LazyCollectionというオブジェクトが返される模様。
foreachとかしてると、その度にクエリや該当取得方法が走るっぽいです。

github.com

ここで、クエリをLazyCollectionに内包させるっぽい?なるほどー!

何が嬉しい?

foreach ($lazy_collection as $user) { // Eloquentで生成したら、ここでクエリが走ってモデルclass取得
    いろんな処理
}

この時、$lazy_collectionを生成している方法がどのDBなのか、どんなクエリなのかは、このCollectionが持っています。
仮に取得方法が変わったとしても、このforeachを回すコードを書いた側は、
どんな取得方法なのかを考えずに、foreachを動かすことが出来ます。

ここで最初の悩みに戻りますが、これなら、ServiceにはとにかくLazyCollectionを渡してやれば、
Repositoryがどんな実装になろうが、差し替わろうが、Service側には影響がありません。

お、これなら最初の悩み解決しそうφ(・

感想: 楽しみ

感想!楽しみ!

ってことで、まだ使えないのですが、この時点で面白そうなのがわかりますね。

みなさんも、よかったらコード見てみませんか?面白いものが見れますよ?

参考コード

github.com

github.com

github.com