Php 关系的多重需求
我有一个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等于LCDPhp 关系的多重需求,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 因此,如果一个项目没有此元(或其中一个元的值错误),则不应返回该项目
因此,如果一个项目没有此元(或其中一个元的值错误),则不应返回该项目 您可以使用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);
})
}
就这些。如果出现意外情况,请始终检查内部