tp6通过闭包方式连表查询的问题
业务背景:
最近在做龙巅广告系统,使用了新的tp6框架
相关数据结构:
advert_plan 广告计划表
advert_plan_position 广告计划位置表
这两个表示 计划表和位置表是 1:n
需求:
在计划列表中的信息已经是包含跨表信息,其中就有位置表里的信息,那该怎么做呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * 广告计划表 * Class AdvertPlan * @package app\common\model * @author:hann * @time:2020-03-10 */ namespace app\common\model; class AdvertPlan extends Common { protected $pk = 'plan_id' ; /** * 位置关联模型 1对n * User: feng * Date: 2020-03-14 * @return \think\model\relation\HasMany */ public function planPosition() { return $this ->hasMany(AdvertPlanPosition:: class , 'plan_id' , 'plan_id' ); } } |
写了 在Plan表的model里写关联模型planPosition方法
然后执行查询如下
1 2 3 4 5 6 7 8 | //连表查询 $data = $model_plan ->with([ 'planPosition' ]) ->field( '*' ) ->where( $where ) ->order( 'plan_id' ) ->paginate(); echo $model_plan ->getLastSql(); dd( $data ->toArray()); |
这样连表查询是没问题的。
但问题来了,根据需求,【要根据位置来筛选计划】,那就得设置位置表的where条件呗,代码如下:
1 2 3 4 5 6 7 8 9 10 | //连表查询,异常 //haswhere 关联表查询失败! $data = $model_plan ->with([ 'planPosition' ]) ->field( '*' ) ->where( $where ) ->hasWhere( 'planPosition' ,[ 'position' =>1]) ->order( 'plan_id' ) ->paginate(); echo $model_plan ->getLastSql(); dd( $data ->toArray()); |
问题来了,提示报错:
1 2 | #0 [10501]PDOException in PDOConnection.php line 722 SQLSTATE[42S22]: Column not found: 1054 Unknown column 'AdvertPlan.plan_id' in 'on clause' |
错误原因:
with不能与hasWhere连用,必须使用with闭包的形式才能实现子模型的条件筛选,具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //连表查询 $data = $model_plan ->with( [ 'planPosition' => function ( $query ) { if (! empty ( $where_position )){ $query ->where( $where_position ); } }, ]) ->field( '*' ) ->where( $where ) ->order( 'plan_id' ) ->paginate(); echo $model_plan ->getLastSql(); dd( $data ->toArray()); |
author:hann
手册链接:https://www.kancloud.cn/manual/thinkphp6_0/1037600
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步