nevadskiy/laravel-many-to-morph

Eloquent 的缺失的多态关系。

0.2.0 2024-04-02 18:17 UTC

This package is auto-updated.

Last update: 2024-09-02 19:08:26 UTC


README

这是一个简化并增强 Laravel Eloquent ORM 中多对多多态关系的包。

Stand With Ukraine

PHPUnit Code Coverage Latest Stable Version License

📚 简介

Laravel Eloquent ORM 中的常见关系之一是 多对多多态关系。虽然它适用于大多数用例,但你可能会遇到需要更优雅解决方案的某些挑战,例如

  1. 当你有许多相关模型时,你需要为每种模型类型定义一个单独的关系。
  2. 难以一次性检索所有相关模型。

此包引入了一种新的多对多形态关系,灵感来源于 Directus 的 多对任一关系,它解决了这些问题。

📝 目录

🔌 安装

通过 Composer 安装此包

composer require nevadskiy/laravel-many-to-morph

📄 文档

配置关系

要配置此关系,您需要使用 HasManyToMorph 特性,该特性提供了一个 manyToMorph 方法来定义关系,如下所示

use Nevadskiy\ManyToMorph\HasManyToMorph;
use Nevadskiy\ManyToMorph\ManyToMorph;

class Tag extends Model
{
    use HasManyToMorph;

    public function taggables(): ManyToMorph
    {
        return $this->manyToMorph('taggable');
    }
}

检索关系

您可以根据以下示例检索关系

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) {
        // ...
    }
}

排序关系

要排序关系,您可以直接在 taggables 关系上使用 orderBy 方法,如下所示

use App\Models\Tag;

$tag = Tag::find(1);

$tag->taggables()->orderBy('position')->get();

预加载关系

预加载关系可以这样做

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();

附加关系

您可以使用以下代码附加关系

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);

您还可以使用带有 pivot 属性的模型附加关系

$tag->taggables()->attach($video, ['score' => 1337]);

分离关系

要分离关系,请使用以下代码

use App\Models\Tag;
use App\Models\Video;

$tag = Tag::find(1);

$video = Video::find(1);

$tag->taggables()->detach($video);

📜 许可

此包是开源的,并按照 MIT 许可证发布。有关更多信息,请参阅 LICENSE 文件。