Laravel中如何对User与Friend关联返回的好友结果按firstname筛选
实现方案
首先在Friend模型中定义两个关联,绑定对应用户表的外键:
// Friend.php public function user() { return $this->belongsTo(User::class, 'user_id'); } public function friendUser() { return $this->belongsTo(User::class, 'friend_id'); }
方案1(推荐:SQL层面筛选,性能更高)
先调整原有searchFriend方法,不要提前执行get()返回集合,改为返回查询构造器,方便后续链式调用筛选逻辑:
public static function searchFriend(){ return Friend::whereUserId(Auth::id()) ->orWhere('friend_id',Auth::id()); }
调用时直接追加关联筛选逻辑即可,$keyword为你要匹配的firstname关键词:
$keyword = '你要筛选的名字关键词'; $friends = Friend::searchFriend() ->where(function ($query) use ($keyword) { // 同时匹配两个关联的firstname字段 $query->whereHas('user', function ($q) use ($keyword) { $q->where('firstname', 'like', "%{$keyword}%"); })->orWhereHas('friendUser', function ($q) use ($keyword) { $q->where('firstname', 'like', "%{$keyword}%"); }); }) ->with(['user', 'friendUser']) // 预加载关联避免N+1查询 ->get();
方案2(无需修改原有searchFriend方法,基于返回集合筛选)
如果不想改动原有方法的返回结构,可以在拿到集合后用PHP层面过滤,仅适合数据量小的场景:
$currentUserId = Auth::id(); $keyword = '你要筛选的名字关键词'; $friends = Friend::searchFriend() ->load(['user', 'friendUser']) // 预加载关联 ->filter(function ($friendRecord) use ($currentUserId, $keyword) { // 取出非当前用户的好友对象 $friendUser = $friendRecord->user_id == $currentUserId ? $friendRecord->friendUser : $friendRecord->user; // 匹配firstname return str_contains($friendUser->firstname, $keyword); });
内容的提问来源于stack exchange,提问作者CoderTn
相关产品推荐
相关产品推荐

