Laravel关联查询:如何基于主表RequestedUnit的type字段过滤关联数据?
问题描述
当前使用Laravel构造的查询代码如下:
$data['requested_units'] = RequestedUnit::with([ 'user', 'agent_warrants' => function ($q) { $q->where('type', RequestedUnit::AgentSecurityWarrant); } ]) ->where('status', RequestedGrant::REQUESTED) ->get();
存在的问题:在关联agent_warrants的闭包查询中,使用where指定type字段时,框架默认该字段属于agent_warrants表,但实际type字段位于主表RequestedUnit中,需要基于主表字段过滤关联数据。
解决方案
分两种常见场景处理:
场景1:只获取主表type符合条件的记录并加载关联
如果需求是仅筛选出主表RequestedUnit中type为AgentSecurityWarrant、且status为REQUESTED的记录,同时加载它们的user和agent_warrants关联,只需将type的条件移到主查询的where中即可:
$data['requested_units'] = RequestedUnit::with(['user', 'agent_warrants']) ->where('status', RequestedGrant::REQUESTED) ->where('type', RequestedUnit::AgentSecurityWarrant) ->get();
场景2:获取所有符合status的记录,但仅主表type符合条件时加载关联
如果需要保留所有status为REQUESTED的主表记录,但仅当主表type为AgentSecurityWarrant时才加载对应的agent_warrants关联,可以通过whereExists关联主表字段实现:
$data['requested_units'] = RequestedUnit::with(['user']) ->where('status', RequestedGrant::REQUESTED) ->with(['agent_warrants' => function ($q) { $q->whereExists(function ($subQuery) { $subQuery->select(DB::raw(1)) ->from('requested_units as ru') ->whereColumn('ru.id', 'agent_warrants.requested_unit_id') ->where('ru.type', RequestedUnit::AgentSecurityWarrant); }); }]) ->get();
注:第一种场景是业务中最常用的,先筛选主表数据再加载对应关联;第二种场景适用于需要保留全部主表记录,但仅部分记录加载关联的特殊需求。
内容的提问来源于stack exchange,提问作者Arsalan Khan
相关产品推荐
相关产品推荐

