Magic Collection adds powerful features to Laravel Eloquent collections.
It lets you call model relationships directly on a collection of models, and includes an Artisan command to generate
custom collection classes.
- Call relationships on a collection of models:
Example:$users->blogs(where $user is a collection) - Automatically merges related results using
flatMap - Safe handling of empty collections
- Define custom collection classes per model
- Artisan command to generate collections:
php artisan make:collection
Insted of doing something like below:
In below example, We considerd that User model has blogs ralationship method defined.
$users = User::get();
$blogs = collect();
foreach($users as $user)
{
$blogs = $blogs->concat($user->blogs);
}OR
$blogs = User::get()->flatMap(fn ($user) => $user->blogs ?? []);now you can do this directly on $users
$blogs = User::get()->blogs();Via Composer
composer require winavin/magic-collection- Use the Trait on your models
use Winavin\Collections\UsesMagicCollections;
class User extends Model
{
use UsesMagicCollections;
}- (Optional) Create a custom collection for a model
php artisan make:collection
This command creates a collection class in the App\Collections folder.
If the collection name matches your model name and path (like YourModelCollection for YourModel Model), it will be used automatically.
You can set any other Collection::class name in your model:
class YourModel extends Model
{
protected function useCollection(): string
{
return \App\Collections\CustomYourModelCollection::class;
}Absolutely! Here's a "Known Errors" section in proper Markdown format for your README.md, including clear steps to
resolve trait method collisions (like the one with newCollection()):
You may see this error if you're using another trait or package (like HasRecursiveRelationships) that also defines a
newCollection() method:
Trait method Winavin\MagicCollection\Traits\UsesMagicCollections::newCollection has not been applied as App\Models\YourModel::newCollection, because of collision with Other Trait's newCollection method.
If your model needs to use both MagicCollection and another custom collection (like one from another package), follow
these steps:
php artisan make:collection YourModelCollectionThis creates App\Collections\YourModelCollection.
In your new collection file, replace:
use Winavin\MagicCollection\Collections\BaseCollection;
class YourModelCollection extends BaseCollectionwith the class from the conflicting package, for example:
- use Winavin\MagicCollection\Collections\BaseCollection;
+ use Staudenmeir\LaravelAdjacencyList\Eloquent\Collection as AdjacencyCollection;
+ use Winavin\MagicCollection\Collections\Trait\BaseCollectionTrait;
- class YourModelCollection extends BaseCollection
+ class YourModelCollection extends AdjacencyCollection
{
+ use BaseCollectionTrait;
// MagicCollection features + AdjacencyCollection features
}In your model (e.g., App\Models\YourModel), override the method:
- use Winavin\Collections\UsesMagicCollections;
class YourModel extends Model
{
- use UsesMagicCollections;
+ public function newCollection(array $models = [])
+ {
+ return new \App\Collections\YourModelCollection($models);
+ }
}This will use your custom collection with both features.
Please see the changelog for more information on what has changed recently.
MIT. Please see the license file for more information.