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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:12:44  来源:igfitidea点击:

Eloquent Parent-Child relationship on same model

phplaravellaravel-5eloquentlaravel-5.1

提问by Kiran LM

I have a model CourseModule, and each of the items are related to the same model.

我有一个模型CourseModule,每个项目都与同一个模型相关。

Database Structure:

数据库结构:

enter image description here

在此处输入图片说明

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/baumpackage 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 getDescendantsto get all children and nested children and toHierarchyto get a complete tree hierarchy.

使用此包,您可以使用诸如getDescendants获取所有子项和嵌套子项以及toHierarchy获取完整树层次结构的方法。

Wikipedia - Nested Set Model

维基百科 - 嵌套集模型

Baum - Nested Set pattern for Laravel's Eloquent ORM

Baum - Laravel 的 Eloquent ORM 的嵌套集模式

Managing Hierarchical Data in MySQL

在 MySQL 中管理分层数据

回答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();