Laravel 5.8 Eloquent关联查询:按用户关联客户过滤Relatorios
解决Laravel 5.8中获取用户所属分组下关联报表并过滤的问题
首先,咱们先梳理下你的问题和初始代码的问题:
你的初始代码 User::with('grupos.relatorios.cliente')->get()->find($id); 存在两个明显的问题:
- 先调用
get()获取所有用户数据,再用find($id)筛选当前用户,这完全是浪费性能,直接用auth()->user()就能拿到当前认证用户,不需要绕这么大弯。 - 没有对关联的
Relatorio添加任何过滤条件,所以会拿到分组下所有的报表,不符合你按client_id匹配的需求。
至于你遇到的SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_id' in 'where clause'错误,原因很明确:你在尝试过滤Relatorio的时候,错误地引用了user_id字段,但Relatorio表本身并没有这个字段——因为User和Relatorio之间没有直接的关联关系,它们是通过Grupo间接关联的,所以不能直接在Relatorio的查询里用user_id作为条件。
接下来给你两种可行的解决方案,根据你的需求选择:
方案一:加载用户数据并附带过滤后的报表
如果你需要保留用户和分组的层级结构,同时只展示符合client_id条件的报表,可以用关联加载的约束方法:
// 直接获取当前认证用户,并加载指定关联 $user = auth()->user()->load([ 'grupos.relatorios' => function ($query) use ($user) { // 过滤报表的client_id与当前用户的client_id一致 $query->where('client_id', $user->client_id); } ]); // 之后可以通过$user->grupos访问分组,每个分组下的relatorios就是过滤后的结果
方案二:直接获取所有符合条件的报表集合
如果你只需要最终的Relatorio数据,不需要用户和分组的结构,可以用whereHas来关联查询:
$relatorios = Relatorio::whereHas('grupo.users', function ($query) { // 确保报表所属的分组包含当前用户 $query->where('id', auth()->id()); }) ->where('client_id', auth()->user()->client_id) // 过滤client_id匹配的报表 ->get();
额外注意:确保模型关联的正确性
为了上面的查询能正常工作,你需要确认各个模型的关联方法定义正确,比如:
User模型:
public function cliente() { return $this->belongsTo(Cliente::class, 'client_id'); } public function grupos() { // 假设用户和分组的中间表名为user_grupo,根据实际情况调整 return $this->belongsToMany(Grupo::class, 'user_grupo'); }
Grupo模型:
public function relatorios() { return $this->hasMany(Relatorio::class, 'grupo_id'); } public function users() { return $this->belongsToMany(User::class, 'user_grupo'); }
Relatorio模型:
public function cliente() { return $this->belongsTo(Cliente::class, 'client_id'); } public function grupo() { return $this->belongsTo(Grupo::class, 'grupo_id'); }
这样就能确保关联查询的字段和表都正确匹配,避免出现类似找不到字段的错误。
内容的提问来源于stack exchange,提问作者XLannes
相关产品推荐
相关产品推荐

