wake-up-neo.net

Eloquente Eltern-Kind-Beziehung am selben Modell

Ich habe ein Modell CourseModule, und alle Elemente beziehen sich auf dasselbe Modell.

Datenbankstruktur:

 enter image description here

Beziehung im Modell:

    public function parent()
    {
        return $this->belongsTo('App\CourseModule','parent_id')->where('parent_id',0);
    }

    public function children()
    {
        return $this->hasMany('App\CourseModule','parent_id');
    }

Ich habe folgendes versucht, aber es gibt nur eine Beziehungsebene zurück.

Versucht:

CourseModule::with('children')->get();

Ich versuche, eine Json-Ausgabe wie die folgende zu erstellen:

Erwartete Ausgabe:

[
  {
    "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": []
              }
            ]
          }
        ]
      }
    ]
  }
]

Ich verstehe nicht, wie man die inneren Kinderobjekte bekommt.

14
Kiran LM

Sie müssten rekursiv die Kinder bekommen, wenn Sie eine solche unbekannte Tiefe haben.

Eine andere Option ist die Verwendung des verschachtelten Mengenmodells anstelle des adjacency-Listenmodells. Sie können so etwas wie baum/baum package für Laravel für verschachtelte Sets verwenden.

"Ein verschachtelter Satz ist eine intelligente Methode zum Implementieren eines geordneten Baums, der schnelle, nicht rekursive Abfragen ermöglicht." - https://github.com/etrepat/baum

Mit diesem Paket haben Sie Methoden wie getDescendants, um alle untergeordneten und verschachtelten Kinder zu erhalten, und toHierarchy, um eine vollständige Baumhierarchie zu erhalten.

Wikipedia - Verschachteltes Satzmodell

Baum - Verschachteltes Set-Muster für Laravel's Eloquent ORM

Verwalten von hierarchischen Daten in MySQL

5
lagbox

Sie sollten with('children') in der untergeordneten Relation Und with('parent') in den übergeordneten Relationen verwenden.

Damit Ihr Code rekursiv ist:

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');
}

Hinweis: Vergewissern Sie sich, dass Ihr Code einige oder andere Exit-Bedingungen hat. Andernfalls endet er in einer endlosen Schleife.

10
Shyam Achuthan

hier ist die Antwort, die dir helfen kann

Ich denke, Sie müssen es rekursiv tun, um den ganzen Baum abzurufen:

$data = CourseModule::with('child_rec');

Rekursive Funktion

Dies kann Ihnen je nach Anforderung helfen.

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');
}
4

Sie können immer eine eigene rekursive Funktion erstellen. In meinem Fall mache ich den folgenden Code. 

<?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;

    }

}
2
Pablo Morales

Modellfunktion:

public function Children()
{ 
    return $this->hasMany(self::class, 'Parent', 'Id')->with('Children');
} 

Controller-Funktion:

Menu::with("Children")->where(["Parent" => 0])->get(); 
1
Ravikumar

ihre Modellbeziehung sollte so aussehen

     // 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;
    }
0
Abdulbasit