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,我们同时检查了两种关注关系:
f1表判断:登录用户(follower_id = $login_id)是否关注了目标用户(following_id = users.id)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
相关产品推荐
相关产品推荐

