【问题标题】:Laravel Eloquent - writing a select query based on related objectsLaravel Eloquent - 编写基于相关对象的选择查询
【发布时间】:2020-08-28 11:02:37
【问题描述】:

抱歉标题有点奇怪,但我有一点问题,即使把我的问题写成一行,我希望至少有人能理解我在下面写的内容。

我有 4 个表(当然还有 Laravel 模型)- scriptruns、executables、executablestatuses 和 scriptlogs(不,我没有命名这些表)。

'scriptruns' 有一个名为 'executable_id' 的 'executables' 外键,并且 Scriptrun 模型有一个 executables() 方法。 'executables' 对 'executablestatuses' 有一个名为“executablestatus_id”的 FK(当然 Executable 模型类有一个 executablestatus() 方法)。 'executablestatuses' 是一个简单的表,它有一个 ID 和一个名称(以及其他不重要的东西)。 'scriptlogs' 对 'scriptruns' 有一个名为 'scriptrun_id' 的 FK(当然 Scriptlog 模型类有一个 scriptrun() 方法)。

我有一个视图,我想在其中显示 scriptun,它的可执行状态不同于 id:3 - name:'deleted',并且有一个日志(意思是 count($scriptrun->scriptlogs) > 0 )并显示最新的实例优先。那么如何使用 Eloquent 正确编写“选择查询”呢?

到目前为止我所做的是我做到了

Scriptrun::orderBy('created_at', 'desc')->get();

之后是一个 foreach 循环,在该循环中我检查了每个 scriptrun 是否有一个可执行文件,其可执行文件状态不同于已删除,以及日志数量是否 > 0,这就是我发送到视图的内容。是的,它丑得要命,而且可能离效率还很远,但它确实有效。然而,现在的问题是 \App\Scriptrun 有数百个(很快也会有数千个)实例,这意味着分页是绝对必要的,这就是我迷失的地方。如果我使用 foreach 循环使用我的“过滤”,我最终会得到一个数组,并且没有在那里定义 paginate() 方法,或者我可以尝试实现我自己的分页,这可以说是在重新发明轮子,可能不会任何与内置功能一样高效的地方。

感谢任何帮助

【问题讨论】:

  • 您的 4 个模型之间是否设置了关系?如果是这样,您应该能够执行 ScriptRun::whereHas('executables', function($subQuery){ $subQuery->whereHas('executable_status', function($subSubQuery){ $subSubQuery->where('status', '!=', 'deleted'); } })->orderBy('created_at')->get(); (或类似的)并完全避免 foreach 循环。然后你也可以对其进行分页等等。如果你可以发布模型的相关部分(至少是类和关系),那将非常有帮助
  • 你太棒了!你的评论不是 100% 正确,但它把我踢到了正确的方向
  • 优秀:) 看起来不错!是的,只要您可以使用关系查询函数而不是循环,请尝试;它更高效且(通常)更清洁。很高兴你成功了!

标签: php laravel


【解决方案1】:

感谢蒂姆刘易斯,我能够做到这一点。 对我来说正确的解决方案是

 $runs = Scriptrun::whereHas('executable', function($subQuery) {
            $subQuery->whereHas('executablestatus', function ($subSubQuery) {
                $subSubQuery->where('id', '!=',  (\App\Executablestatus::deletedStatus())->id);
            });
        })
            ->whereHas('logs')
            ->orderBy('scriptruns.created_at', 'desc')
            ->paginate(15);

【讨论】:

    猜你喜欢
    • 2017-11-23
    • 2023-03-10
    • 2020-05-13
    • 1970-01-01
    • 2021-07-20
    • 2020-04-22
    • 2021-12-17
    • 1970-01-01
    • 2020-01-23
    相关资源
    最近更新 更多