【问题标题】:Conditional wherehas with Laravel EloquentLaravel Eloquent 的条件 wherehas
【发布时间】:2019-12-28 09:05:24
【问题描述】:

我在两个表onetwo 中有一个相似的(area)值,这两个表与主表master 有关系。一次,master 表将只有一个关系中的数据,而另一个关系将是 null

使用这种架构,我有一个搜索页面,用户可以在其中搜索与这些表相关的任何值,并且搜索字段以AND 条件放置。

在这里,如果用户为area 输入一些值,我需要检查任一表(onetwo)中是否存在区域值,而不会破坏AND 条件。尝试了下面的代码,但它违反了AND 规则并考虑了OR。有什么建议可以解决吗?

$result =  Master::where(function ($query) use ($request) {
    if ($request->filter == true) {
        $query->where('user_id', Auth::user()->id);
    }
    // other conditions here
    if (!empty($request->area_from) && !empty($request->area_to)) {
        $query->whereHas('one', function ($query) use ($request) {
            $query->whereBetween('area', [$request->area_from, $request->area_to]);
        });
        $query->orWhereHas('two', function ($query) use ($request) {
            $query->whereBetween('area', [$request->area_from, $request->area_to]);
        });
    }
    // other conditions here

})->with(['one', 'two'])->paginate($request->item);

【问题讨论】:

  • 我不太明白你打破AND的意思。
  • @IGP 所有搜索字段应以AND 分隔。但是由于orWhereHas,这里的条件是从该文件中获取所有内容,而不考虑以前的条件。
  • 哦!只需将另一个 where 闭包封装 whereHas

标签: php mysql laravel laravel-5 eloquent


【解决方案1】:

使用更接近的 where 并在内部设置条件可能会正常工作

$master = Master::with('one')->with('two');
$result = $master->where(function($subQuery)
{   
    $subQuery->whereHas('one', function ( $query ) {
        $query->whereBetween('area', [$request->area_from, $request->area_to] ); //assuming  $request->area_from, $request->area_to is range of value
    })
    ->orWhereHas('two', function ( $query ) {
        $query->whereBetween('area', [$request->area_from, $request->area_to] );
    });
});

【讨论】:

    【解决方案2】:

    您可以创建合并关系refer this link

    public function mergedOneAndTwo($value)
    {
        // There two calls return collections
        // as defined in relations.
        $onedata= $this->one;
        $twodata= $this->two;
    
        // Merge collections and return single collection.
        return $onedata->merge($twodata);
    }
    


    并使用whereHas('mergedOneAndTwo')

    【讨论】:

      【解决方案3】:

      您将所有 where 语句都包含在括号中。我认为您想要做的是将查询的第一部分从 where 子句中拉出,以便您可以轻松地将 whereHas 部分括在括号中。

      // Initialise the model
      $query = new Master;
      
      // Start building the query
      if ($request->filter == true) {
          $query->where('user_id', Auth::user()->id);
      }
      
      if (!empty($request->area_from) && !empty($request->area_to)) {
          // Wrap these in brackets so we don't interfare with the previous where
          $query->where(function($query2) use ($request) {
              $query2->whereHas('one', function ($query3) use ($request) {
                  $query3->whereBetween('area', [$request->area_from, $request->area_to]);
              });
              $query2->orWhereHas('two', function ($query3) use ($request) {
                  $query3->whereBetween('area', [$request->area_from, $request->area_to]);
              });
          }
      }
      
      $query->with(['one', 'two'])->paginate($request->item);
      

      【讨论】:

        猜你喜欢
        • 2019-07-08
        • 2021-08-23
        • 1970-01-01
        • 2017-06-09
        • 2020-09-16
        • 2020-12-23
        • 2014-09-30
        • 2021-05-25
        • 2018-06-19
        相关资源
        最近更新 更多