Laravel对关系的多重要求

时间:2015-12-17 14:19:24

标签: php laravel laravel-5 eloquent

我有一个Item表,Meta表和一个Item_Meta表,它包含Items的所有元记录。一个项目有很多元记录。

Item_meta包含以下列: Item_id | Meta_id |值

让我说我有一个要求: 要求1 - [' Meta_id' => 1,'价值' => '新'] 要求2 - [' Meta_id' => 3,'价值' => ' LCD']

我需要构建一个查询获取所有项目,其中id_id等于new的meta_id,以及id为3的meta_id等于LCD。

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

2 个答案:

答案 0 :(得分:2)

您可以使用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->元关系称为 metas

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

$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();

答案 1 :(得分:0)

在提出问题之前,我尝试过上一个答案中的第一种方法,但它失败了所以我认为它有错误。但看到和那个答案后,似乎我不明白。所以我挖掘了Laravel Eloquent内部,这就是我发现的:

Eloquent Build类“:: where”方法在返回实例之前更改$ this->查询属性。这是代码:

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;
}

注意“$ this-> query-> addNestedWhereQuery($ query-> getQuery(),$ boolean);”在6号线。

Builder类“:: 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);
    })
 }

这就是全部。如果某些事情发生意外,请务必与内部人员核实