Laravel 模型关联Eager Loading预加载解决N+1查询的正确实现方法
正确实现方案
第一步:给User模型新增专属关联
先在App\Models\User中定义用于预加载当前登录用户关注状态的关联,你可以根据自己的关注表字段调整对应字段名(示例默认关注表为followers,follower_id代表关注者ID,user_id代表被关注者ID):
public function followedByAuthUser() { return $this->hasOne(\App\Models\Follower::class, 'follower_id', 'id') ->where('user_id', \Auth::id()); }
第二步:查询时预加载关联
修改分页查询代码,预加载上面定义的关联即可:
$followingUsers = $user->followerUsers() ->with('followedByAuthUser') ->paginate(80);
第三步:调整Blade判断逻辑(可选)
你可以直接通过预加载的关联判断关注状态,不需要再调用isFollowed方法执行额外查询:
@if ($follower->followedByAuthUser) <!-- 已关注的逻辑 --> @endif
如果不想改动原有Blade代码,可以修改isFollowed方法优先读取预加载的关联数据:
public function isFollowed($user) { // 优先读取预加载的关联,避免重复查库 if ($user->relationLoaded('followedByAuthUser')) { return $user->followedByAuthUser !== null; } // 保留原有兜底逻辑 return \App\Models\Follower::where('user_id', $this->id) ->where('follower_id', $user->id) ->exists(); }
原有写法错误原因
- 写
with('App\Follower')报错是因为with()方法接收的参数是模型中定义的关联方法名称,不是Follower模型的命名空间,你未提前定义对应关联所以触发报错。 - 写
with(Auth::user()->isFollowed($follower))完全不符合语法要求,with()不接收布尔类型的返回值作为参数,无法实现预加载。
内容的提问来源于stack exchange,提问作者Felix
相关产品推荐
相关产品推荐

