如何使用 Eloquent 实现自引用数据透视表关系

Posted

技术标签:

【中文标题】如何使用 Eloquent 实现自引用数据透视表关系【英文标题】:How to implement Self Referencing pivot table relationship with Eloquent 【发布时间】:2017-10-31 10:32:30 【问题描述】:

我有这个场景要实现

“成员 - 专辑” 多对多关系是 cmets。会员可以在任何相册上发布 cmets。相册可以包含来自任意数量成员的 cmets。一些 cmets 可以作为对其他 cmets 的回复发布。

“reply_to”指的是父评论。也就是说,一条评论可以有多个回复。

我在我的项目中使用 Eloquent 和 Lumen 5.5。我已经浏览了这两个文件。我知道如何实现 M:N、M:1 等关系。

我仍然不知道如何在 Eloquent 中使用自定义中间表模型来实现这个场景。非常感谢任何帮助。

注意:为了简单起见,我从 ERD 中删除了其他元素..

【问题讨论】:

【参考方案1】:

试试这个

class Member

    public function comments()
    
        return $this->hasMany(Comment:class, 'Member_id'); // a member may has many comments
    


class Album

    public function comments()
    
        return $this->hasMany(Comment::class, 'Album_id'); // an album may has many comments
    


class Comment

    public function parent()
    
        return $this->belongsTo(Comment::class, 'reply_to'); // self reference
    

    public function member()
    
        return $this->belongsTo(Member::class, 'Member_id'); // a comment should belongs to a member
    

    public function album()
    
        return $this->belongsTo(Album::class, 'Album_id'); // a comment should belongs to an album
    

查询:

Album::with(['comments' => function ($query) 
    $query->with(['parent', 'member]);
])->get();

【讨论】:

评论表是数据透视表或中间表 (laravel.com/docs/5.5/eloquent-relationships#many-to-many)。你还没有在这里使用过。 查看您的表格截图,Comment 表格不是数据透视表。与AlbumMember 的关系是1:N,而不是N:N。想想看,一条评论应该属于一个成员,而不是属于多个成员。 想象一下这条评论是否属于你和我。此外,这条评论应该属于一个帖子而不是多个帖子。 想象一下,如果这条评论也存在于另一个帖子/答案中(有点奇怪)。无论如何,你试过我的答案吗? 这里我正在尝试使用数据透视表来实现解决方案。在您的解决方案中,您没有处理“自引用”。 Comment::parent 方法是你的朋友。获取自我引用:$comment->parent(如果有的话,将返回另一个 Comment 对象)。【参考方案2】:

据我所知。 以下是模型中所需的关系。\

Comments model

Comment::belongsTo('Member'); //add namespace of member model Comment::belongsTo('Albums'); //add namespace of member model

Member model

Member::hasMany('comments');

Album model Album::hasMany('comments');

如果没有得到reply tocmets,您可以在Comment::belongsTo('Albums')->whereNull('replyTo'); 中添加位置

然后可以通过评论 id 获取回复 cmets。

【讨论】:

评论表是数据透视表或中间表 (laravel.com/docs/5.5/eloquent-relationships#many-to-many)。你还没有在这里使用过。 不需要数据透视表,没有它也可以实现。 我知道没有它也可以实现。我想在这种情况下使用数据透视表。

以上是关于如何使用 Eloquent 实现自引用数据透视表关系的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Eloquent 在数据透视表中插入多行?

如何在 laravel 5 中使用 Eloquent 更新数据透视表

如何对 Eloquent 关系中的数据透视表列进行 GROUP 和 SUM?

如何在 Eloquent ORM 中按多对多关系的数据透视表的字段进行排序

在 Eloquent 中使用带有数据透视表字段的访问器

Laravel Eloquent group by 与数据透视表和关系