You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Laravel实现类Twitter的用户好友关系(自关联多对多)

实现Twitter式用户好友关系(自关联多对多)

一、逻辑建模(UML类图)

这种关系的核心是单个User实体通过中间表与自身建立多对多关联,对应UML类结构如下:

  • User类:包含基础属性(id、name、email等),以及两个核心关联:
    • friends():指向当前用户主动关注/添加的其他User实例
    • friendOf():指向主动关注/添加当前用户的其他User实例
  • Friendships中间表:作为关联桥梁,核心字段包括:
    • user_id:发起关联的用户ID(外键关联User.id)
    • friend_id:被关联的用户ID(外键关联User.id)
    • status(可选):用于区分关联状态(比如pending/accepted/rejected,Twitter单向关注可省略)

UML关系描述:

User 与 User 之间通过 Friendships 表建立多对多自关联,其中User.friends通过user_id→friend_id关联目标User,User.friendOf通过friend_id→user_id反向关联发起者User。

二、Laravel Eloquent 具体实现

1. 数据库迁移

创建中间表的迁移文件,配置自关联外键与约束:

Schema::create('friendships', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('user_id');
    $table->unsignedBigInteger('friend_id');
    // 可选:添加状态字段支持好友请求流程
    $table->enum('status', ['pending', 'accepted', 'rejected'])->default('pending');
    $table->timestamps();

    // 外键级联删除
    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    $table->foreign('friend_id')->references('id')->on('users')->onDelete('cascade');

    // 避免重复添加同一好友
    $table->unique(['user_id', 'friend_id']);
});

2. User模型关联定义

在App\Models\User模型中添加两个关联方法,明确中间表与外键映射:

// 获取当前用户主动关注/添加的好友列表
public function friends()
{
    return $this->belongsToMany(User::class, 'friendships', 'user_id', 'friend_id')
                ->withPivot('status') // 若有状态字段,携带该字段数据
                ->withTimestamps();
}

// 获取关注/添加当前用户的用户列表
public function friendOf()
{
    return $this->belongsToMany(User::class, 'friendships', 'friend_id', 'user_id')
                ->withPivot('status')
                ->withTimestamps();
}

3. 常用业务操作示例

添加好友(发起关注/请求)

// 单向关注(类似Twitter)直接关联
$user->friends()->attach($friendId);

// 双向好友请求模式,指定初始状态
$user->friends()->attach($friendId, ['status' => 'pending']);

接受好友请求

// 更新发起请求用户的关联状态为已通过
$user->friendOf()->updateExistingPivot($requesterId, ['status' => 'accepted']);

获取已通过的好友列表

$acceptedFriends = $user->friends()->wherePivot('status', 'accepted')->get();

取消关注/移除好友

$user->friends()->detach($friendId);

内容的提问来源于stack exchange,提问作者Arash Bahariye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:32:19