php 同一模型上雄辩的父子关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34758965/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Eloquent Parent-Child relationship on same model
提问by Kiran LM
I have a model CourseModule
, and each of the items are related to the same model.
我有一个模型CourseModule
,每个项目都与同一个模型相关。
Database Structure:
数据库结构:
Relation in Model:
模型关系:
public function parent()
{
return $this->belongsTo('App\CourseModule','parent_id')->where('parent_id',0);
}
public function children()
{
return $this->hasMany('App\CourseModule','parent_id');
}
I tried the following, but it returns only a single level of relation.
我尝试了以下操作,但它只返回一个单一级别的关系。
Tried:
尝试:
CourseModule::with('children')->get();
I'm trying to create a json output like the following,
我正在尝试创建如下的 json 输出,
Expected Output:
预期输出:
[
{
"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": []
}
]
}
]
}
]
}
]
I don't understand how to get the inner child objects.
我不明白如何获取内部子对象。
采纳答案by lagbox
You would have to recursively get the children if you have an unknown depth like that.
如果你有一个未知的深度,你将不得不递归地得到孩子。
Another option is to use the nested sets modelinstead of the adjacency list model. You can use something like baum/baum
package for Laravel for nested sets.
另一种选择是使用嵌套集模型而不是邻接表模型。您可以baum/baum
为嵌套集使用Laravel 包之类的东西。
"A nested set is a smart way to implement an ordered tree that allows for fast, non-recursive queries." - https://github.com/etrepat/baum
“嵌套集是实现有序树的一种聪明方式,它允许快速、非递归查询。” - https://github.com/etrepat/baum
With this package you have methods like getDescendants
to get all children and nested children and toHierarchy
to get a complete tree hierarchy.
使用此包,您可以使用诸如getDescendants
获取所有子项和嵌套子项以及toHierarchy
获取完整树层次结构的方法。
Baum - Nested Set pattern for Laravel's Eloquent ORM
Baum - Laravel 的 Eloquent ORM 的嵌套集模式
回答by Shyam Achuthan
You should use with('children')
in the children relation
and with('parent')
in the parent relations.
您应该with('children')
在子关系和with('parent')
父关系中使用。
For your code to be recursive:
为了您的代码是递归的:
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');
}
Note:Make sure your code has some or the other exit conditions otherwise it will end up in a never ending loop.
注意:确保您的代码具有某些或其他退出条件,否则它将以永无止境的循环结束。
回答by Sagar Naliyapara
hereis the answer that can help you
这是可以帮助您的答案
I think you you have to do it recursively to retrieve whole tree:
我认为你必须递归地检索整个树:
$data = CourseModule::with('child_rec');
Recursive function
递归函数
This may help you according to your requirement,
这可能会根据您的要求帮助您,
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');
}
回答by Pablo Morales
You can always create your own recursive function, in my case I do as the code as follow.
您始终可以创建自己的递归函数,在我的情况下,我按照以下代码进行操作。
<?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;
}
}
回答by Abdulbasit
your model relationship should like this
你的模特关系应该是这样的
// 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;
}
回答by Ravikumar
Model Function:
模型功能:
public function Children()
{
return $this->hasMany(self::class, 'Parent', 'Id')->with('Children');
}
Controller Function:
控制器功能:
Menu::with("Children")->where(["Parent" => 0])->get();