ModelクラスにあるsetAppends関数をCollectionクラスでも使いたいなーと思ったのでその方法を紹介します。
前提
例えば、以下のようにして、UserモデルのCollectionクラスに対して、setAppendsを使用すると
$userCollection = User:all();
$userCollection->setAppends(['example']);
以下のようなエラーになる。
Method Illuminate\\Database\\Eloquent\\Collection::setAppends does not exist.
これはCollectionクラスにはsetAppendsという関数は存在していないためです。
ModelクラスにはsetAppends関数が存在していますが、Collectionクラスには存在していません。
そういう時はCollectionクラスにMacroを作成して、あたかもCollectionクラスにModelクラスのsetAppends関数と同様のものが存在しているかのようにしましょう。
作り方
1.Macroを記載するサービスプロバイダを作成します。
php artisan make:provider MacroServiceProvider
2.作成したMacroServiceProvider.phpのboot関数内にCollectionクラスにMacroを追加するように記載
<?php
namespace App\Providers;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\ServiceProvider;
class MacroServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
// CollectionクラスにsetAppendsというマクロを登録
Collection::macro('setAppends', function ($accessorList) {
return $this->map(function ($model) use ($accessorList) {
// Collectionから一つずつModelを取り出して、ModelクラスのsetAppendsを使用
return $model->setAppends($accessorList);
});
});
}
}
3.config/app.phpにプロバイダ(MacroServiceProvider)を登録
// 省略
'providers' => [
// 省略
App\Providers\MacroServiceProvider::class,
],
完成
これで、以下のようにCollectionクラスに登録したマクロのsetAppendsを呼び出せるようになり、ModelクラスのsetAppends関数と同じ動きになる。
$userCollection = User:all();
$userCollection->setAppends(['example']);
コメント