我可能没有使用正确的措词,但是我的问题是这样:
我有这个查询
$result = Table_one_model::with(['Table_two' => function($query) use ($thing_id) {
$query->where('thing_id', $thing_id);
}])
->select('col_one', 'col_two')
->get();
我想向table_two中的select添加更多内容,但是,如果我将其添加到上方现有的select中,如select('col_one', 'col_two', 'col_from_other_table')
,则不起作用,并且如果我将select添加到table_two查询中像下面这样也不起作用:
$result = Table_one_model::with(['Table_two' => function($query) use ($thing_id) {
$query->where('thing_id', $thing_id)->select('col_from_other_table');
}])
->select('col_one', 'col_two')
->get();
在这两种情况下,我都得到结果,但是table_two
的结果只是显示为'null'
不选择第二个表,我得到以下结果:
{
"col_one": 0,
"col_two": 0,
"table_one": {
"id":1,
"blah":0,
"col_from_other_table":0
...all the contents of table two
}
}
通过table_two查询中的选择,我得到了:
{
"col_one": 0,
"col_two": 0,
"table_one": {
null
}
}
将select与其他select列放在同一位置时,它完全中断并表示该列不存在。
我认为这只是通过table_one.col_from_other_table
或table_one->col_from_other_table
之类的方式到达该列的问题,但我不能在select中使用任何一个
有什么想法吗?
答案 0 :(得分:0)
您无法在with()
方法中选择列,而将其移出父级列。
尝试使用toSql()
和getQueryLog()
查看原始SQL:
$result = Table_one_model::with(
[
'Table_two' => function($query) use ($thing_id) {
$query->where('thing_id', $thing_id);
}
]
)
->select('col_one', 'col_two');
print_r($result->toSql()); #=> this will return only one table_one raw sql. So that you cannot select table_two column from table_one.
\DB::enableQueryLog();
print_r(\DB::getQueryLog()); #=> this will return two raw sql, the one is table_one, and second is table_two. They are splited.
Laravel可以将它们水合在一起。
检查源代码:
/**
* Set the relationships that should be eager loaded.
*
* @param mixed $relations
* @return $this
*/
public function with($relations)
{
$eagerLoad = $this->parseWithRelations(is_string($relations) ? func_get_args() : $relations);
$this->eagerLoad = array_merge($this->eagerLoad, $eagerLoad);
return $this;
}
返回eagerLoad
,我们检查eagerLoad源代码:
/**
* Eagerly load the relationship on a set of models.
*
* @param array $models
* @param string $name
* @param \Closure $constraints
* @return array
*/
protected function eagerLoadRelation(array $models, $name, Closure $constraints)
{
// First we will "back up" the existing where conditions on the query so we can
// add our eager constraints. Then we will merge the wheres that were on the
// query back to it in order that any where conditions might be specified.
$relation = $this->getRelation($name);
$relation->addEagerConstraints($models);
$constraints($relation);
// Once we have the results, we just match those back up to their parent models
// using the relationship instance. Then we just return the finished arrays
// of models which have been eagerly hydrated and are readied for return.
return $relation->match(
$relation->initRelation($models, $name),
$relation->getEager(), $name
);
}
它表示一旦获得结果,我们就可以使用关系实例将那些结果与其父模型进行匹配。然后,我们只返回完成的模型数组,这些模型已经急需水化并准备返回。
因此,如果要获取其他表列, 我想我有两种推荐方法:
使用with()
并对其进行循环,将col从子查询获取到父查询。构建所需的数据结构
尝试使用leftjoin
,它可以选择两个表列,并在db之外按table_one分组。构建所需的数据结构。
答案 1 :(得分:0)
还需要根据关系选择ID或外部ID。这就是为什么它抛出空值的原因。例如,假设有两个模型。
Parent: id (pk), name, phone, email
Child: id (pk), name, phone, email, parent_id (fk)
假设我们只需要获取名称。在Eloquent中看起来像这样:
$children = Child::select('children.name'. 'children.parent_id') /* Need to select children.parent_id */
->with(['parent' => function ($query) {
$query->select('parents.id', 'parents.name'); /* Need to select parents.id */
}])
->get();
$parents = Parent::select('parents.id', 'parents.name') /* Need to select parents.id */
->with(['children' => function ($query) {
$query->select('children.name', 'children.parent_id'); /* Need to select children.parent_id */
}])
->get();
答案 2 :(得分:0)
'Table_two' => function($query) use ($thing_id) {
$query->where('thing_id', $thing_id);
}
只需在子查询条件中附加查询对象
$query->from('other_table')
->selectRaw('col')
->where('condition', '>=', val)
->where('condition', val);
它将为您生成子查询