【问题标题】:Eloquent: check if relationship has certain conditionsEloquent:检查关系是否有一定的条件
【发布时间】:2021-11-13 16:21:12
【问题描述】:

我有一个模型 SurveyhasOne 相关,另一个模型 InstallationhasMany 另一个模型 Assignment 相关。 所以我定义了一个像这样的hasManyThrough 关系

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

我想编写一个查询来获取与调查关联的 Assignments 的 assignment.type 不为 0、1、2、3 和 4 的任何 Survey

即 每个调查应该有 5 个任务并记录

Survey => [
[Assignment => [type = 0]]
[Assignment => [type = 1]]
[Assignment => [type = 2]]
[Assignment => [type = 3]]
[Assignment => [type = 4]]
]

我试过这个查询

 $schedulables = Survey::whereNotNull('installer_id')
            ->where(function ($query) {
                $query
                    ->whereNotExists(function ($query) {
                        return $query->raw('SELECT * FROM assignments,installations where assignments.installation_id = installations.id and installations.survey_id = surveys.id and assignments.type= 1');
                    })
                    ->orwhereNotExists(function ($query) {
                        return $query->raw('SELECT * FROM assignments,installations where assignments.installation_id = installations.id and installations.survey_id = surveys.id and assignments.type= 2');
                    })
                    ->orwhereNotExists(function ($query) {
                        return $query->raw('SELECT * FROM assignments,installations where assignments.installation_id = installations.id and installations.survey_id = surveys.id and assignments.type= 3');
                    })
                    ->orwhereNotExists(function ($query) {
                        return $query->raw('SELECT * FROM assignments,installations where assignments.installation_id = installations.id and installations.survey_id = surveys.id and assignments.type= 4');
                    });

            })
            ->with('customer', 'installer', 'installation')
            ->latest('updated_at')->get();

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

【问题讨论】:

    标签: sql laravel eloquent laravel-query-builder


    【解决方案1】:

    我的最终解决方案是在 Survey 模型中创建这些关系

     public function assignment_outdoor(){
            return $this->hasManyThrough(Assignment::class,Installation::class)
                ->where('assignments.type',1)
                ->where('assignments.status',2);
        }
        public function assignment_indoor(){
            return $this->hasManyThrough(Assignment::class,Installation::class)
                ->where('assignments.type',2)
                ->where('assignments.status',2);
        }
        public function assignment_testing_activation(){
            return $this->hasManyThrough(Assignment::class,Installation::class)
                ->where('assignments.type',3)
                ->where('assignments.status',2);
        }
        public function assignment_lm_splicing(){
            return $this->hasManyThrough(Assignment::class,Installation::class)
                ->where('assignments.type',4)
                ->where('assignments.status',2);
        }
    
    

    然后使用doesntHaveordoesntHave 构建查询。

    $schedulables = Survey::when($installer_filter, function ($query, $installer_filter) {
                return $query->where('installer_id', $installer_filter);
            })
                ->whereNotNull('installer_id')
    //actual solution
                ->where(function ($query) {
                    return $query
    
                        ->doesntHave('assignment_outdoor')
                        ->orDoesntHave('assignment_indoor')
                        ->orDoesntHave('assignment_testing_activation')
                        ->orDoesntHave('assignment_lm_splicing');
    
                })
    //end
                ->doesntHave('network_job_order_customer')
                ->with('customer', 'installer', 'installation')
                ->latest('updated_at');
    

    【讨论】:

      【解决方案2】:

      如果我正确理解了您的问题,您可以使用whereHas()whereNotIn() 来实现您的目标:

      $schedulables = Survey
          ::with('customer', 'installer', 'installation')
          ->whereNotNull('installer_id')
          ->whereHas('assignments', function ($query) {
              $query->whereNotIn('type', [0, 1, 2, 3, 4]);
          })
          ->latest('updated_at')
          ->get();
      

      【讨论】:

      • 请在您的答案中包含相关文档,而不仅仅是链接到它。如果链接失效,它会有所帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-20
      • 2014-11-15
      • 2013-10-07
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多