kingmaker / laravel-many-to-many-self-relationship

通过中转表提供双向关联的Laravel同一模型上的多对多关系。

2.1.4 2024-05-23 09:45 UTC

This package is auto-updated.

Last update: 2024-09-23 10:29:26 UTC


README

Version Packagist Downloads Laravel Tests License

此包扩展了Laravel的belongsToMany关系,允许同一模型在单个中转表条目上实现双向关联。

安装

可以通过Composer安装此包。

composer require kingmaker/laravel-many-to-many-self-relationship

版本

此包适用于特定版本的Laravel。

用法

Model类中包含HasBelongsToManySelfRelation特性,并按以下方式定义关系方法

use Illuminate\Database\Eloquent\Model;
use Kingmaker\Illuminate\Eloquent\Relations\HasBelongsToManySelfRelation;

class Post extends Model {

    use HasBelongsToManySelfRelation;

    public function relatedPosts()
    {
        return $this->belongsToManySelf('related_posts', 'post1', 'post2');
    }
}

这样非常简单,并具有所有在belongsToMany()上可用的方法。相关帖子可以像任何正常关系一样访问。

$post = Post::first();
$post->relatedPosts; // returns Collection of Related Posts

这是对Eloquent提供的原生BelongsToMany类的扩展。

示例

假设存在'posts'表和'related_posts'表。Post表示博客中的帖子,它可以有与它们类似的关联帖子。

posts:
| id | title | body |
+----+-------+------+
| 1  | a     | ...  |
| 2  | b     | ...  |
| 3  | c     | ...  |
| 4  | d     | ...  |
+----+-------+------+

related_posts:
| id | post1 | post2 |
+----+-------+-------+
| 1  | 1     | 3     |
| 2  | 1     | 4     |
| 3  | 2     | 1     |
| 4  | 2     | 3     |
| 5  | 3     | 4     |
| 6  | 4     | 2     |
+----+-------+-------+

当调用关系时,belongsToManySelf关系提供了双向关联。

Post::find(1)->relatedPosts; // returns Posts with id 2, 3, 4
Post::find(2)->relatedPosts; // returns Posts with id 1, 3, 4
Post::find(3)->relatedPosts; // returns Posts with id 1, 2, 4
Post::find(4)->relatedPosts; // returns Posts with id 1, 2, 3

注意

如果实体在中转表上通过两行相关联,则可能会返回重复的相关对象。

用例

这种双向关联的多对多关系可以在一些特殊情况下使用。这种关系并不适用于所有场景。

a) 相关帖子/产品

考虑一个博客或购物网站,其中我们有一个与另一个相关的post / product。当通过BelongsToMany关系匹配相关实体时,当一个帖子/产品被关联到另一个帖子/产品时,从第一个对象获取relatedPostrelatedProduct将返回第二个,但反过来则不成立(即,从第二个获取第一个帖子/产品作为相关帖子/产品)。

b) 社交媒体中的好友列表

在社交媒体中,用户之间互相成为好友的概念可以使用此关系轻松实现(不是关注者 & 被关注者,只是互为好友)。一旦一个用户将另一个用户添加为好友,我们就可以附加用户,在用此关系使用时不需要关心反向关联。

注意:关注者 & 被关注者的概念必须使用Laravel的BelongsToMany关系。此关系用于类似于Facebook的好友

c) 聊天中的消息

聊天应用中的消息,其中消息从一个用户指向另一个用户。此关系允许检索所有向特定用户发送消息的用户。

注意:在这种情况下可能会有重复的可能性

API参考

HasBelongsToManySelfRelation特性为您的模型添加了belongsToManySelf方法。

    /**
     * create the BelongsToManySelf relation on the same Model via a pivot table
     *
     * @param string $table Pivot table name
     * @param string $pivotKey1 Pivot table foreign key 1
     * @param string $pivotKey2 Pivot table foreign key 2
     * @param string|null $relatedKey Related key on the parent table
     * @param string|null $relation Relation name
     * @return BelongsToManySelf
     */
    public function belongsToManySelf(string $table, string $pivotKey1, string $pivotKey2, $relatedKey = null, $relation = null)

BelongsToManySelf是Eloquent BelongsToMany类的具体/子/子类。因此,所有在BelongsToMany上可用的方法也在这个关系上可用。

已知问题

在此包或底层数据库引擎中发现了以下问题/问题。

  • haswhereHas约束在MySQL < v8.0.14将不起作用

提示

  • 为了提高关系性能,创建两个枢轴表索引,例如 (枢轴键1,枢轴键2)(枢轴键2,枢轴键1)

贡献

欢迎贡献!

请随意打开问题并提交 拉取请求

您也可以支持我
"Buy Me A Coffee"