递归关系和带约束的嵌套预加载
Recursive relationship and nested eager loading with constraints
我正在尝试使用递归关系的 where 约束创建嵌套的预加载
模型和查询模拟:
模型层次结构
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Hierarchy extends Model
{
protected $table = 'hierarchy';
protected $primaryKey = 'id_hierarchy';
protected $fillable = [
'name',
'parent_id'
];
/**
* @return HasMany
*
* This method implement recursive relationship
*/
public function children()
{
return $this->hasMany(Hierarchy::class, 'parent_id')->with('children');
}
/**
* @return HasMany
*/
public function grandchildren()
{
return $this->hasMany(Grandchild::class, 'id_hierarchy');
}
}
模特孙子
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Grandchild extends Model
{
protected $table = 'grandchildren';
protected $primaryKey = 'id';
protected $fillable = [
'id_hierarchy',
'id_something'
'name'
];
/**
* @return BelongsTo
*/
public function hierarchy()
{
return $this->belongsTo(Hierarchy::class, 'id_hierarchy');
}
}
以下查询没有 return 孙辈,因为它应该是;
public function read($id)
{
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children.grandchildren' => function ($query) use($id) {
$query->where('id_something', $id);
}])
->get();
}
问题出在约束中,因为在下面的查询中它 return 是孙子(尽管没有过滤,因为它没有 where 条件)
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children.grandchildren'])
->get();
提前感谢您提出解决此问题的建议。
已编辑:
由于代码是对真实案例的模拟,我添加了'id_something'以更清楚地涉及到什么。
'id_something' 与此处未表示的另一个模型有关
假设HomeCity
是GrandChild
的相关模型之一,关系定义为
//GrandChild.php
public function home_city()
{
return $this->hasMany(HomeCity::class);
}
然后查询到returnGrandChild
记录谁住在HomeCity
(id_something
是home_city
上的一列table) by $id
可以写成:
public function read($id)
{
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children' => function ($query) use($id) {
$query->with(['grandchildren' => function($query) use($id) {
$query->whereHas('home_city', fn($query) => $query->where('id_something', $id);
}]);
}])
->get();
}
我正在尝试使用递归关系的 where 约束创建嵌套的预加载
模型和查询模拟:
模型层次结构
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Hierarchy extends Model
{
protected $table = 'hierarchy';
protected $primaryKey = 'id_hierarchy';
protected $fillable = [
'name',
'parent_id'
];
/**
* @return HasMany
*
* This method implement recursive relationship
*/
public function children()
{
return $this->hasMany(Hierarchy::class, 'parent_id')->with('children');
}
/**
* @return HasMany
*/
public function grandchildren()
{
return $this->hasMany(Grandchild::class, 'id_hierarchy');
}
}
模特孙子
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Grandchild extends Model
{
protected $table = 'grandchildren';
protected $primaryKey = 'id';
protected $fillable = [
'id_hierarchy',
'id_something'
'name'
];
/**
* @return BelongsTo
*/
public function hierarchy()
{
return $this->belongsTo(Hierarchy::class, 'id_hierarchy');
}
}
以下查询没有 return 孙辈,因为它应该是;
public function read($id)
{
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children.grandchildren' => function ($query) use($id) {
$query->where('id_something', $id);
}])
->get();
}
问题出在约束中,因为在下面的查询中它 return 是孙子(尽管没有过滤,因为它没有 where 条件)
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children.grandchildren'])
->get();
提前感谢您提出解决此问题的建议。
已编辑:
由于代码是对真实案例的模拟,我添加了'id_something'以更清楚地涉及到什么。
'id_something' 与此处未表示的另一个模型有关
假设HomeCity
是GrandChild
的相关模型之一,关系定义为
//GrandChild.php
public function home_city()
{
return $this->hasMany(HomeCity::class);
}
然后查询到returnGrandChild
记录谁住在HomeCity
(id_something
是home_city
上的一列table) by $id
可以写成:
public function read($id)
{
$data = Hierarchy::query()
->whereNull('parent_id')
->with(['children' => function ($query) use($id) {
$query->with(['grandchildren' => function($query) use($id) {
$query->whereHas('home_city', fn($query) => $query->where('id_something', $id);
}]);
}])
->get();
}