I have a function that only accepts an Eloquent Collection
. This is okay, but really I'd like to specify that it can only accept collections of a certain model. Is it possible to specify that we only want a collection of a certain type to function arguments?
This is what I have now:
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
/**
* @param EloquentCollection $companies
* @return array
*/
public function transformCompanies(EloquentCollection $companies)
{
$companies->each(function($company){
// do things with the company object..
});
}
The problem I see with it is that it accepts any type of collection. Could I do something like public function transformCompanies(CompaniesCollection $companies)
or how does that work? What would the use
statement be at the top if we wanted this function to only accept an Eloquent collection of the company model?
You can implement your own class that extends Collection
and then specify that you'd like to use that for collections of your model. I've never used the functionality, but something like this should work:
<?php
namespace App\Support;
use Illuminate\Database\Eloquent\Collection;
class CompaniesCollection extends Collection {}
And then define the newCollection()
method in your model:
<?php
namespace App\Models;
use App\Support\CompaniesCollection;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
public function newCollection(array $models = []): CompaniesCollection
{
return new CompaniesCollection($models);
}
}
And now your controller method can have a signature like this:
public function transformCompanies(App\Support\CompaniesCollection $companies);
Coming back to this a few years later, I would suggest just doing this in documentation. Current Laravel code includes generic types so you can simply document your code to accept only Collection<int,Company>
and rely on your IDE and static analysis testing to enforce rules and inform you of problems.
/**
* @param EloquentCollection<int,Company> $companies
* @return array
*/
public function transformCompanies(EloquentCollection $companies)
{
$companies->each(function($company){
// do things with the company object..
});
}