lundi 15 juillet 2019

Flatten laravel nested relationship (parent to descendants)

I have a parent children relationship on my model. What I want is to flatten all those collection including all those descendants of parent.

[
   {
      'name': 'Parent',
      'children': [
         {
             'name': 'First Child',
             'children': [
                {
                    'name': 'First Descendant',
                    'children': [
                        {
                            'name': 'Descendant Child',
                            'children': [
                                {
                                   'name': 'Last Descendant',
                                   'children': []
                                }
                            ]

                        }
                    ]
                }
             ]
         }
      ]
   }
]



I tried the code below. However it only displays the second depth of children. It does not display the next children of the collection.

User.php
public function parent()
{
    return $this->belongsTo(User::class, 'id', 'parent_id');
}

public function children()
{

    return $this->hasMany(User::class,'parent_id', 'id');
}

public function descendants()
{
    return $this->children()->with('descendants');
}

UsersController.php

public function index()
{
    $parent = User::find(1);

    $parent->with('descendants')->find($parent->id);

    $descendants = $this->traverseTree($parent->descendants);

    return response($descendants);
}

protected function traverseTree($subtree)
{
    $descendants = collect([]);

    foreach ($subtree->descendants as $descendant) {

       $descendants->push($descendant);

       if($descendant->descendants instanceof Collection) {

          foreach ($descendant->descendants as $node) {

             $this->traverseTree($node);

             $descendants->push($node);
          }
       }
   }

   return $descendants;
}

Desired Output

[
    {
        'name': 'Parent'
    },
    {
        'name': 'First Child'
    },
    {
        'name': 'First Descendant'
    },
    {
        'name': 'Descendant Child'
    },
    {
        'name': 'Last Descendant' 
    }

]

I am looking forward for your help.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire