Laravel关联预加载能否设置多ON条件?是否需用leftJoin实现
Laravel Eloquent关联预加载添加多ON条件的可行方案
首先明确结论:关联预加载的闭包里不能直接用->on()来添加额外ON条件,因为预加载的关联规则是在模型的关联方法中定义的,with的闭包仅能用于过滤关联数据,无法修改JOIN的ON子句逻辑。
两种可行的实现方式
1. 自定义模型关联(推荐长期复用场景)
在模型中定义包含多ON条件的关联方法,后续预加载时直接调用该关联即可:
比如在TableA模型中新增关联方法:
public function tablebWithFoo() { // 若需将条件严格放在ON子句中(而非WHERE),可这么写: return $this->hasMany(TableB::class) ->join('tableb', function ($join) use ($targetValue) { $join->on('tablea.id', '=', 'tableb.table_a_id') ->on('tableb.foo', '=', $targetValue); }); // 如果WHERE条件能满足业务需求,更简洁的写法: // return $this->hasMany(TableB::class, 'table_a_id')->where('foo', $targetValue); }
之后预加载时直接使用这个自定义关联:
TableA::with('tablebWithFoo.tablec')->get();
2. 直接使用leftJoin(适合单次临时查询)
如果只是单次查询需要该多ON条件,不想修改模型,直接用leftJoin拼接查询即可:
TableA::leftJoin('tableb', function ($join) use ($targetValue) { $join->on('tablea.id', '=', 'tableb.table_a_id') ->on('tableb.foo', '=', $targetValue); }) ->leftJoin('tablec', 'tableb.id', '=', 'tablec.table_b_id') ->groupBy('tablea.name') ->get();
补充说明
预加载的闭包仅支持对关联数据做过滤操作,比如添加WHERE条件、排序、限制返回数量等,无法修改关联的JOIN规则。若要调整JOIN的ON条件,要么在模型的关联方法中预先定义,要么直接使用JOIN语句构建查询。
内容的提问来源于stack exchange,提问作者Daniel Saito
相关产品推荐
相关产品推荐

