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

Laravel v4.2中基于关联查询用户关注状态的问题

解决Laravel 4.2中用户关注关系的双向判断问题

我明白你的需求:只要登录用户和目标用户数组中的任意用户存在单向关注(登录关注对方/对方关注登录)或互相关注,就返回该用户信息并标记关联状态为true。你当前的代码问题在于关联定义和筛选逻辑没有覆盖到「对方关注登录用户」的场景,下面给你两种解决方案:

方案一:使用数据库JOIN高效判断(推荐)

这种方式直接在数据库层面完成关联判断,性能更优,适合数据量较大的场景:

class User extends Eloquent {
    protected $table = 'users';
    protected $primaryKey = 'id';
    protected $guarded = array();
    protected $hidden = array();

    // 可选:保留关联定义用于其他场景
    public function followings() {
        return $this->belongsToMany('User', 'friends', 'follower_id', 'following_id');
    }

    public function followers() {
        return $this->belongsToMany('User', 'friends', 'following_id', 'follower_id');
    }

    public static function get_users_infomation_by_ids($login_id, $users_arr = array()) {
        if (empty($users_arr)) {
            return [];
        }

        $users = User::whereIn('id', $users_arr)
            ->select('id', 'username', 'full_name', 'is_live', 'message_privacy', 'picture')
            // 左连接friends表,判断「登录用户关注当前用户」的情况
            ->leftJoin('friends as f1', function($join) use ($login_id) {
                $join->on('users.id', '=', 'f1.following_id')
                     ->where('f1.follower_id', '=', $login_id);
            })
            // 左连接friends表,判断「当前用户关注登录用户」的情况
            ->leftJoin('friends as f2', function($join) use ($login_id) {
                $join->on('users.id', '=', 'f2.follower_id')
                     ->where('f2.following_id', '=', $login_id);
            })
            // 生成is_connected字段:只要任一关联存在就为1(true)
            ->selectRaw('CASE WHEN f1.id IS NOT NULL OR f2.id IS NOT NULL THEN 1 ELSE 0 END as is_connected')
            ->get();

        return $users->isEmpty() ? [] : $users->toArray();
    }
}

为什么这个方案能解决问题?

你之前的mutual_friends关联只覆盖了「当前用户作为关注者(follower)」的场景,而没有处理「当前用户被他人关注」的情况。通过两次leftJoin,我们同时检查了两种关注关系:

  1. f1表判断:登录用户(follower_id = $login_id)是否关注了目标用户(following_id = users.id)
  2. f2表判断:目标用户(follower_id = users.id)是否关注了登录用户(following_id = $login_id)
    只要其中任一条件成立,is_connected就会被标记为1。

方案二:使用Eloquent关联加载(ORM风格)

如果你更倾向于Laravel的ORM写法,也可以通过加载双向关联后在内存中判断:

class User extends Eloquent {
    protected $table = 'users';
    protected $primaryKey = 'id';
    protected $guarded = array();
    protected $hidden = array();

    // 当前用户关注的人
    public function followings() {
        return $this->belongsToMany('User', 'friends', 'follower_id', 'following_id');
    }

    // 关注当前用户的人
    public function followers() {
        return $this->belongsToMany('User', 'friends', 'following_id', 'follower_id');
    }

    public static function get_users_infomation_by_ids($login_id, $users_arr = array()) {
        if (empty($users_arr)) {
            return [];
        }

        $users = User::whereIn('id', $users_arr)
            ->with([
                // 加载当前用户的粉丝中是否包含登录用户
                'followers' => function($query) use ($login_id) {
                    $query->where('id', $login_id);
                },
                // 加载当前用户关注的人中是否包含登录用户
                'followings' => function($query) use ($login_id) {
                    $query->where('id', $login_id);
                }
            ])
            ->select('id', 'username', 'full_name', 'is_live', 'message_privacy', 'picture')
            ->get()
            ->map(function($user) {
                // 判断是否存在任一关注关系
                $user->is_connected = !$user->followers->isEmpty() || !$user->followings->isEmpty();
                // 移除不需要的关联数据,精简返回结果
                unset($user->followers, $user->followings);
                return $user;
            });

        return $users->isEmpty() ? [] : $users->toArray();
    }
}

效果验证

修改后,ID为18363的用户会被标记is_connected: 1,因为登录用户已经关注了他,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Rizwan Saleem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:46:07