雄辩:约束关系属性为 0 或关系不存在的热向荷载关系


Eloquent: Constraining an eager load relation where relation property is 0 or relation doesn't exist

我想得到所有Report模型,其中ReportUpload status的属性等于0或ReportUpload关系不存在。ReportReportUpload模型具有一对一的关系,ReportUpload属于Report

有点不确定如何使用雄辩的关系约束或任何其他方法来实现这一点。任何帮助将不胜感激。

这是我当前的代码:

// initial query
$reports = Report::whereHas('link', function($query) {
        $query->where('status', 'complete');
    })->with('student', 'course', 'institution', 'reportUpload');

// apply constraint
if ($request->has('uploadStatus')) {
    $uploadStatus = $request->has('uploadStatus'); // 0 or 1
    if ($uploadStatus === 0) {
        $reports = $reports
            ->whereDoesntHave('reportUpload')
            ->orWhereHas('reportUpload', function($query) use ($uploadStatus) {
                $query->where('status', $uploadStatus);
            });
    } else {
        $reports = $reports->whereHas('reportUpload', function($query) use ($uploadStatus) {
            $query->where('status', $uploadStatus);
        });
    }
}

代码不会产生所需的结果。

编辑

尝试这种方法,但不确定它是否正确:

$reports = $reports
    ->where(function ($query) use ($uploadStatus) {
        $query
            ->whereDoesntHave('reportUpload')
            ->orWhereHas('reportUpload', function($query) use ($uploadStatus) {
                $query->where('status', $uploadStatus);
            });
    });

首先,初始代码中存在一些错误。

1 - 您正在检查请求是否has上传状态。然后,$uploadStatus == $request->has将永远true.

if ($request->has('uploadStatus')) {
    $uploadStatus = $request->has('uploadStatus');

所以我想你可能想要:

if ($request->has('uploadStatus')) {
    $uploadStatus = $request->input('uploadStatus');

2 - 您正在严格比较$uploadStatus === 0这可能不起作用,因为请求可能会返回字符串'0'而不是整数,因此您应该与==进行比较或将$uploadStatus转换为(int)

在此之后,我认为您在问题中添加的代码按预期工作:

$reports = $reports
->where(function ($query) use ($uploadStatus) {
    $query
        ->whereDoesntHave('reportUpload')
        ->orWhereHas('reportUpload', function($query) use ($uploadStatus) {
            $query->where('status', $uploadStatus);
        });
});

因为封装查询where会将其放在括号之间。

尝试分离查询。 whereDoesntHave可能会对orWhereHas进行负计数,即使它是一个or语句:

$reportsNoUpload = $reports
            ->whereDoesntHave('reportUpload')->get();
$reportsIncomplete = $reports
            ->orWhereHas('reportUpload', function($query) use ($uploadStatus) {
                $query->where('status', $uploadStatus);
            })->get();
$reports = $reportsNoUpload->merge($reportsIncomplete);