我有一个模型CourseModule
,每个项目都与相同的模型相关。
public function parent()
{
return $this->belongsTo('App\CourseModule','parent_id')->where('parent_id',0);
}
public function children()
{
return $this->hasMany('App\CourseModule','parent_id');
}
我尝试了以下内容,但它只返回一个级别的关系。
CourseModule::with('children')->get();
我正在尝试创建一个类似于以下的json输出,
[
{
"id": "1",
"parent_id": "0",
"course_id": "2",
"name": "Parent",
"description": "first parent",
"order_id": "1",
"created_at": "-0001-11-30 00:00:00",
"updated_at": "-0001-11-30 00:00:00",
"children": [
{
"id": "2",
"parent_id": "1",
"course_id": "2",
"name": "Child 1",
"description": "child of parent",
"order_id": "2",
"created_at": "-0001-11-30 00:00:00",
"updated_at": "-0001-11-30 00:00:00",
"children": [
{
"id": "3",
"parent_id": "2",
"course_id": "2",
"name": "Child2",
"description": "child of child1",
"order_id": "2",
"created_at": "-0001-11-30 00:00:00",
"updated_at": "-0001-11-30 00:00:00",
"children": [
{
"id": "4",
"parent_id": "3",
"course_id": "2",
"name": "Child 3",
"description": "child of child 2",
"order_id": "2",
"created_at": "-0001-11-30 00:00:00",
"updated_at": "-0001-11-30 00:00:00",
"children": []
}
]
}
]
}
]
}
]
我不明白如何获取内部子对象。
如果您有这样的未知深度,则必须以递归方式获取子项。
另一种选择是使用嵌套集模型而不是邻接列表模型。对于嵌套集,您可以使用类似baum/baum
包的内容来使用Laravel。
“嵌套集是实现有序树的智能方法,允许快速,非递归查询。” - https://github.com/etrepat/baum
使用这个包你可以使用像getDescendants
这样的方法来获取所有子项和嵌套子项,并使用toHierarchy
来获得完整的树层次结构。
您应该在子关系中使用with('children')
,在父关系中使用with('parent')
。
为了使您的代码递归:
public function parent()
{
return $this->belongsTo('App\CourseModule','parent_id')->where('parent_id',0)->with('parent');
}
public function children()
{
return $this->hasMany('App\CourseModule','parent_id')->with('children');
}
注意:确保您的代码具有某些或其他退出条件,否则它将以永无止境的循环结束。
here是可以帮助你的答案
我认为你必须以递归方式检索整棵树:
$data = CourseModule::with('child_rec');
这可以根据您的要求帮助您,
public function child()
{
return $this->hasMany('App\CourseModule', 'parent');
}
public function children_rec()
{
return $this->child()->with('children_rec');
// which is equivalent to:
// return $this->hasMany('App\CourseModule', 'parent')->with('children_rec);
}
// parent
public function parent()
{
return $this->belongsTo('App\CourseModule','parent');
}
// all ascendants
public function parent_rec()
{
return $this->parent()->with('parent_rec');
}
你可以随时创建自己的递归函数,在我的例子中,我做的代码如下。
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Akmeh\Uuid;
/**
* Class Location
* @package Domain\Models
*/
class Location extends Model
{
use Uuid;
/**
* Indicates if the IDs are auto-incrementing.
*
* @var bool
*/
public $incrementing = false;
public $timestamps = false;
/**
* @param string $id
* @param array $tree
* @return array
*/
public static function getTree(string $id, array $tree = []): array
{
$lowestLevel = Location::where('id', $id)->first();
if (!$lowestLevel) {
return $tree;
}
$tree[] = $lowestLevel->toArray();
if ($lowestLevel->parent_id !== 0) {
$tree = Location::getTree($lowestLevel->parent_id, $tree);
}
return $tree;
}
}
型号功能:
public function Children()
{
return $this->hasMany(self::class, 'Parent', 'Id')->with('Children');
}
控制器功能:
Menu::with("Children")->where(["Parent" => 0])->get();
你的模特关系应该是这样的
// parent relation
public function parent(){
return $this->belongsTo(self::class , 'parent_id');
}
//child relation
public function children()
{
return $this->hasMany(self::class ,'parent_id');
}
public function ascendings()
{
$ascendings = collect();
$user = $this;
while($user->parent) {
$ascendings->push($user->parent);
if ($user->parent) {
$user = $user->parent;
}
}
return $ascendings;
}
public function descendings()
{
$descendings = collect();
$children = $this->children;
while ($children->count()) {
$child = $children->shift();
$descendings->push($child);
$children = $children->merge($child->children);
}
return $descendings;
}