nevadskiy / laravel-many-to-morph
The missing polymorphic relationship for Eloquent.
Requires
- php: ^7.4 || ^8.0.2
- illuminate/database: ^8.0 || ^9.0 || ^10.0 || ^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.19 || ^3.0
- phpunit/phpunit: ^9.6
This package is auto-updated.
Last update: 2024-11-02 19:25:14 UTC
README
A package that simplifies and enhances Many-To-Many polymorphic relationships in Laravel's Eloquent ORM.
📚 Introduction
One common type of relationship in Laravel's Eloquent ORM is the Many-To-Many polymorphic relation. While it works well for most use cases, you might encounter certain challenges that require more elegant solutions, for example:
- When you have numerous related models, you need to define a separate relation for each type of model.
- It is hard to retrieve all related models at once.
This package introduces a new Many-To-Morph relationship, inspired by the Directus's Many-to-Any relation that handles these problems.
📝 Table of Contents
🔌 Installation
Install the package via Composer:
composer require nevadskiy/laravel-many-to-morph
📄 Documentation
Configuring Relationship
To configure this relationship, you need to use the HasManyToMorph
trait, which provides a manyToMorph
method for defining the relation as follows:
use Nevadskiy\ManyToMorph\HasManyToMorph; use Nevadskiy\ManyToMorph\ManyToMorph; class Tag extends Model { use HasManyToMorph; public function taggables(): ManyToMorph { return $this->manyToMorph('taggable'); } }
Retrieving Relationships
You can retrieve relationships as shown below:
use App\Models\Tag; use App\Models\Post; use App\Models\Video; $tag = Tag::find(1); foreach ($tag->taggables as $taggable) { if ($taggable instanceof Post) { // ... } else if ($taggable instanceof Video) { // ... } }
Ordering Relationships
To order relationships, you can use the orderBy
method directly on the taggables
relation like so:
use App\Models\Tag; $tag = Tag::find(1); $tag->taggables()->orderBy('position')->get();
Eager Loading Relationships
Eager loading relationships can be done like this:
use App\Models\Tag; use App\Models\Post; use App\Models\Video; $tags = Tag::query() ->with(['taggables' => function (ManyToMorph $taggables) { $taggables->morphWith([ Post::class => ['media'], Video::class => ['previews'], ]); }]) ->get();
Attaching Relationships
You can attach relationships with the following code:
use App\Models\Tag; use App\Models\Post; use App\Models\Video; $tag = Tag::find(1); $post = Post::find(1); $tag->taggables()->attach($post); $video = Video::find(1);
You can also attach a model with pivot attributes:
$tag->taggables()->attach($video, ['score' => 1337]);
Detaching Relationships
To detach relationships, use the following code:
use App\Models\Tag; use App\Models\Video; $tag = Tag::find(1); $video = Video::find(1); $tag->taggables()->detach($video);
📜 License
This package is open-source and is released under the MIT License. Please refer to the LICENSE file for more information.