Laravel:如何仅在模型关系存在时才查询模型关系

Posted

技术标签:

【中文标题】Laravel:如何仅在模型关系存在时才查询模型关系【英文标题】:Laravel: How to query a Model Relationship only if it exists 【发布时间】:2021-11-12 05:36:29 【问题描述】:

我有一个模型Survey,其列installer_idhasOne 相关,另一个模型InstallationhasMany 另一个模型Assignment 相关。

我想编写一个查询来获取所有Survey,其中installer_id 不为空,并且如果存在Assignment,则检查所有分配(如果有status is != 2 即状态= 0 或1)返回调查.

我尝试了这个查询,但它没有捕获“如果存在分配,则检查状态”部分

 $surveys = Survey::whereNotNull('installer_id')
            ->orWhereHas('installation',function ($query) 
                return $query->whereHas('assignments',function ($q)
                    return $q->where('status','!=', 2 );
                );
        )->get();

我还尝试在模型中定义hasManyThrough 关系。

    public function assignments()
    
        return $this->hasManyThrough(Assignment::class,Installation::class);
    

然后使用这个查询

 $schedulables = Survey::whereNotNull('installer_id')
            ->orWherehas('assignments',function ($query)
                return $query->where('assignments.status','!=', 2 );
            )->get()

如有任何建议和帮助,我们将不胜感激

【问题讨论】:

【参考方案1】:

我认为您的方法是正确的,但是如果您已经要检查 whereHas,则不需要 whereNotNull,所以我认为这种方式就足够了:

$surveys = Survey::whereHas('installation',function ($query) 
                return $query->whereHas('assignments',function ($q)
                    return $q->where('status','!=', 2 );
                );
        )->get();

我认为您的代码中缺少 ->get();,这就是您没有得到结果的原因

【讨论】:

我仍在尝试获取所有调查,但如果他们有与分配相关的安装 - 分配状态不应为 2。 另外,我正在检查installer_id 是否不为空,这是调查表上与installations 关系分开的列【参考方案2】:

Original answer

我需要的是whereDoesntHave 方法。

$surveys = Survey::whereNotNull('installer_id')
    ->whereDoesntHave('installation.assignments', fn ($query) => $query->where('status', 2))
    ->get();

【讨论】:

以上是关于Laravel:如何仅在模型关系存在时才查询模型关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent ORM - 选择所有两个关系都不存在的模型时,生成的 SQL 和查询构建器结果不匹配

Laravel 雄辩与查询构建器的优缺点

如何在laravel中获取嵌套关系模型[重复]

Laravel 查询模型关系

如何查询 Laravel Eloquent 的 belongsTo 关系?

如何在 Laravel 中定义 Eloquent 关系