Laravel框架中从二级关联取值后如何向三级关联传递参数
功能实现方案
方案1:改造动态关联定义(最优推荐)
statusType本质是一级关联RelationShipName对应模型自身的字段属性,无需外部传参,直接在关联方法内读取当前模型实例的属性即可,原生支持预加载,不会产生N+1查询问题。
改造后关联模型代码:
/////// 关联模型内的动态关联方法 ////// public function anotherRelationShipName() { // 直接读取当前实例的statusType字段值,无需外部传入 $statusType = $this->statusType; switch ($statusType){ case 0: return $this->belongsTo(/* 对应0的关联模型代码 */); case 1: return $this->belongsTo(/* 对应1的关联模型代码 */); case 6: return $this->belongsTo(/* 对应6的关联模型代码 */); case 2: return $this->belongsTo(/* 对应2的关联模型代码 */); case 3: return $this->belongsTo(/* 对应3的关联模型代码 */); case 4: return $this->belongsTo(/* 对应4的关联模型代码 */); default: return null; } }
控制器调用代码:
$Variable = ModelName::where('id', $id)->with([ 'RelationShipName' => function ($query) use ($startDate) { $query->whereDate('date', '>=', $startDate)->orderBy('date', 'DESC'); }, 'RelationShipName.anotherRelationShipName' ])->get();
方案2:延迟加载(适合不修改原有关联方法的场景)
如果需要保留原有带参数的关联方法,可以先预加载一级关联,再遍历实例加载二级动态关联,仅适合一级关联数据量较小的场景,数据量大时会产生N+1查询。
实现代码:
// 第一步:预加载一级关联 $Variable = ModelName::where('id', $id)->with([ 'RelationShipName' => function ($query) use ($startDate) { $query->whereDate('date', '>=', $startDate)->orderBy('date', 'DESC'); } ])->get(); // 第二步:遍历加载二级动态关联 $Variable->each(function ($mainModel) { $mainModel->RelationShipName->each(function ($relationItem) { // 获取当前关联项的statusType,传入关联方法 $statusType = $relationItem->statusType; $relationItem->setRelation('anotherRelationShipName', $relationItem->Name($statusType)->first()); }); });
注意事项
Laravel原生的with预加载不支持直接给关联方法传递动态参数,因为预加载阶段还未读取到关联表的字段值,无法提前获取每个实例对应的statusType。
内容的提问来源于stack exchange,提问作者Raveel Sabir
相关产品推荐
相关产品推荐

