【问题标题】:How to apply filter with relational table using with statement如何使用 with 语句对关系表应用过滤器
【发布时间】:2020-08-31 04:50:59
【问题描述】:

我编写了一个代码来过滤关系数据,但我没有得到好的结果。这是代码。父查询和同一个查询是独立工作的。

public function get(Request $request, Company $company, Survey $survey)
{
    $this->authorize('update', $survey->company);
    $search = $request->get('search');
    $query = EsAnswer::where(['company_id' => $company->id, 'survey_id' => $survey->id])
        ->orderByDesc('created_at')
        ->with(['employee'=> function ($q) use($search) {
            $q->where('first_name', 'LIKE', "%{$search}%");
            $q->orwhere('last_name', 'LIKE', "%{$search}%");
            $q->select('id', 'first_name', 'last_name');   
        }]);
    if ($request->has('start_date')) {
        $query->whereDate('created_at', '>=', $request->start_date);
    }
    if ($request->has('end_date')) {
        $query->whereDate('created_at', '<=', $request->end_date);
    }

    $answers = $query->get()->groupBy('submission_id');
        // ->paginate('100');
    return $answers;
}

当我使用这个时

{
    "search":""
}

我收到了这样的回复:

{
    "id": 2,
    "company_id": 1,
    "employee_id": 1,
    "survey_id": 2,
    "es_question_id": 1,
    "answer": "done",
    "submission_id": "1",
    "mark_as_read": 1,
    "created_at": "2020-08-19 12:18:25",
    "updated_at": "2020-08-26 06:55:21",
    "employee": {
        "id": 1,
        "first_name": "Baseapp",
        "last_name": "saw"
    }
}

当我尝试按另一个表中存在的员工姓名进行搜索时,如果数据存在,则应过滤数据并给出响应,但如果员工姓名或搜索数据不存在,则数据不应给出任何响应。如何处理?

{
    "search":"sure"
}


{
    "id": 2,
    "company_id": 1,
    "employee_id": 1,
    "survey_id": 2,
    "es_question_id": 1,
    "answer": "done",
    "submission_id": "1",
    "mark_as_read": 1,
    "created_at": "2020-08-19 12:18:25",
    "updated_at": "2020-08-26 06:55:21",
    "employee": null
}

这里的数据为空,但为什么显示父数据。请帮助并给出另一个想法来过滤关系数据。

【问题讨论】:

    标签: php laravel filter laravel-query-builder


    【解决方案1】:

    我们使用whereHas 过滤相关表。所以像这样使用它

    $query = EsAnswer::with('employee:id,first_name,last_name')
            ->where(['company_id' => $company->id, 'survey_id' => $survey->id])
            ->whereHas('employee', function($query) use($search) {
                $query->where('first_name', 'LIKE', "%{$search}%")
                    ->orwhere('last_name', 'LIKE', "%{$search}%");
            })
            ->orderByDesc('created_at');
    

    这将在您的相关表中搜索,如果未找到任何内容,则返回 null。我为eager load 数据添加了优雅的方式。你也应该看看这个。

    【讨论】:

      【解决方案2】:

      它使用 whereHas,然后是 With :

      $query = EsAnswer::where(['company_id' => $company->id, 'survey_id' => $survey->id])
          ->orderByDesc('created_at')
          ->whereHas('employee', function ($q) use($search) {
            return $q->where('first_name', 'LIKE', "%{$search}%")
            ->orwhere('last_name', 'LIKE', "%{$search}%");   
          })->with(['employee' => function ($q){
              $q->select('id', 'first_name', 'last_name');
          }]);
      

      【讨论】:

        【解决方案3】:

        使用whereHas()函数

          $query = EsAnswer::with('employee:id,first_name,last_name')
                ->where(['company_id' => $company->id, 'survey_id' => $survey->id])
                ->whereHas('employee', function($query) use($search) {
                    $query->where('first_name', 'LIKE', "%$search%")
                        ->orwhere('last_name', 'LIKE', "%$search%");
                })
                ->orderByDesc('created_at');
        

        参考链接https://laravel.com/docs/7.x/eloquent-relationships#querying-relationship-existence

        【讨论】:

        • 答案没有用,两者都是一样的。我希望如果我想按员工姓名搜索,那么关系数据应该过滤,否则结果为空。但这里只查询过滤员工模型。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-04
        • 2017-05-07
        • 2017-01-31
        • 1970-01-01
        相关资源
        最近更新 更多