Laravel 使用自定义查询预加载嵌套关系

Posted

技术标签:

【中文标题】Laravel 使用自定义查询预加载嵌套关系【英文标题】:Laravel eager loading nested relationships with custom query 【发布时间】:2015-05-02 07:13:13 【问题描述】:

我有可以工作的代码,但没有急切地加载嵌套关系。

$projects = Project::with('organization')
        ->leftJoin('stages', 'stages.project_id', '=', 'projects.id')
        ->leftJoin('activities', 'activities.stage_id', '=', 'stages.id')
        ->leftJoin('tasks', 'tasks.activity_id', '=', 'activities.id')
        ->select('projects.*',  DB::raw('SUM(IF(tasks.status = 4, score, 0)) AS score'), 
                                DB::raw('SUM(tasks.score) AS total_score'))
        ->groupBy('projects.id')
        ->get();

我想通过急切加载嵌套关系来做到这一点,如果我没有这些自定义选择(total_score 和 score),我会这样做

$projects = Project::with('stages.activities.tasks');

但问题出现在那些自定义选择(score 和 total_score)上。 我尝试了类似的方法,但没有成功

$projects = Project::with(['stages', 'activities', 'tasks' => function($q)  
        $q->select( DB::raw('SUM(IF(tasks.status = 4, score, 0)) AS score'), 
                    DB::raw('SUM(tasks.score) AS total_score')); 
    ])->get();

【问题讨论】:

理想情况下的 SQL 会是什么样子?如果我对您的问题的理解正确,那么执行 2 个查询可能会更有效 【参考方案1】:

类似的东西应该可以工作:

$projects = $project::with(array('stages' => function($q)
 
   $q->with(array('activities' => function($q)
   
     $q->with(array('tasks' => function($q)
     
        $q->groupBy('tasks.id');
        $q->addselect([
            DB::raw('SUM(IF(tasks.status = 4, score, 0)) AS score'),
            DB::raw('SUM(tasks.score) AS total_score')
            ]);
       ));
     ));
   ))
 ->get();

如果您的函数需要更多参数function($q) use ($arg)

【讨论】:

以上是关于Laravel 使用自定义查询预加载嵌套关系的主要内容,如果未能解决你的问题,请参考以下文章

ruby 与缓存和预加载的自定义关系(ActiveRecord)

Laravel 自定义数据透视表关系和急切加载?

Django:ModelForm 使用自定义查询预填充复选框

相关模型 eloquent laravel 中的自定义查询

如何在 laravel 4.2 中使用带有自定义预过滤器的 AJAX 上传 CSV 文件

Laravel:如何设置带有条件的自定义列?