Php 关系的多重需求

Php 关系的多重需求,php,laravel,laravel-5,eloquent,Php,Laravel,Laravel 5,Eloquent,我有一个Item表、Meta表和Item_Meta表,其中包含了Items的所有元记录。一个项目有许多元记录 Item_meta具有以下列: 项目|元| id |值 假设我有一个要求: 需求1-['Meta_id'=>1,'value'=>'new'] 要求2-['Meta_id'=>3,'value'=>'LCD'] 我需要构建一个查询来获取所有项目,其中meta_id的id 1等于new,meta_id的id 3等于LCD 因此,如果一个项目没有此元(或其中一个元的值错误),则不应返回该项目

我有一个Item表、Meta表和Item_Meta表,其中包含了Items的所有元记录。一个项目有许多元记录

Item_meta具有以下列: 项目|元| id |值

假设我有一个要求: 需求1-['Meta_id'=>1,'value'=>'new'] 要求2-['Meta_id'=>3,'value'=>'LCD']

我需要构建一个查询来获取所有项目,其中meta_id的id 1等于new,meta_id的id 3等于LCD


因此,如果一个项目没有此元(或其中一个元的值错误),则不应返回该项目

您可以使用Eloquent的whereHas()方法根据关系的属性筛选模型。在您的情况下,以下代码应该可以做到这一点:

$items = Item::whereHas('metas', function($query) {
  $query->where('Meta_id', 1);
  $query->where('value', 'new);
})
->whereHas('metas', function($query) {
  $query->where('Meta_id', 3);
  $query->where('value', 'LCD);
})
->get();
我假设您的item->meta关系称为metas

您还可以使用另一种形式的usingwhereHas(),其中提供匹配的相关记录的数量。代码会稍微复杂一些,但会导致执行查询中的子选择减少:

$items = Item::whereHas('metas', function($query) {
  $query->where('Meta_id', 1);
  $query->where('value', 'new);
  $query->orWhere(function($query2) {
    $query2->where('Meta_id', 3);
    $query2->where('value', 'LCD);
  };
}, '=', 2)
->get();

在提出问题之前,我尝试了前面答案中的第一种方法,但失败了,所以我认为这是一个错误。但是在看到这个答案之后,我似乎不明白什么。因此,我挖掘了Laravel雄辩的内部结构,以下是我发现的:

雄辩的构建类“::where”方法在返回实例之前更改$this->query属性。代码如下:

public function where($column, $operator = null, $value = null, $boolean = 'and')
{
    if ($column instanceof Closure) {
        $query = $this->model->newQueryWithoutScopes();

        call_user_func($column, $query);

        $this->query->addNestedWhereQuery($query->getQuery(), $boolean);
    } else {
        call_user_func_array([$this->query, 'where'], func_get_args());
    }

    return $this;
}
注意第6行的“$this->query->addNestedWhereQuery($query->getQuery(),$boolean);”

生成器类“::whereHas”方法不修改“$this->query”属性

public function whereHas($relation, Closure $callback, $operator = '>=', $count = 1)
{
    return $this->has($relation, $operator, $count, 'and', $callback);
}
那么,这和我的问题有什么关系。我创建了如下查询:

$query = Item::where('active',1); 
然后我添加了条件:

if($meta){
    $query->whereHas('metas', function($query) {
        $query->where('Meta_id', 1);
        $query->where('value', 'new);
    })
    ->whereHas('metas', function($query) {
      $query->where('Meta_id', 3);
      $query->where('value', 'LCD);
    })
 }
然后执行查询:

$query->get();
错误与::whereHas方法有关,我要做的是将whereHas结果赋值给变量:

 if($meta){
    $query = $query->whereHas('metas', function($query) {
        $query->where('Meta_id', 1);
        $query->where('value', 'new);
    })
    ->whereHas('metas', function($query) {
      $query->where('Meta_id', 3);
      $query->where('value', 'LCD);
    })
 }
就这些。如果出现意外情况,请始终检查内部