Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nolros's avatar
Level 23

Dynamic depth nested parent / child relation on same model / table

Is there a way to get iterate in a dynamic depth relation on the same table e.g. lets say I have CMS DOM model that could be between 3 - 6 levels deep. is there a way to iterate until no more children exist?

    public function examplePseudoCodeRelation()
    {
        while (is_int($this->parent_id) ) {
            return $this->hasOne(TheCurrentClass::class, 'parent_id', 'id');
        }
    }
0 likes
6 replies
nolros's avatar
Level 23

@SaeedPrez I'm using nested sets, but the part I'm struggling with are relations at each level i.e.

I can get all descendants and maintain relationship integrity with the getPage() example below. However, what I'm unable to solve with nested sets is dynamically loading other relations e.g. menu, document, image, etc. at each level. If I attempt a ->with() or a ->load() it will do so at level one which means I have to lazy load these relations through some recursive method at every depth.

This will return all sections with child sections for n depth:

    public function getPage()
    {
        $getPage = $this->page
            ->where('slug', $this->pageSlug)
            ->with(['theme','layout.sections'])
            ->first();

        foreach ($getPage->layout->sections as $section) {
            $section->setRelation('children', $section->getDescendants()->toHierarchy()) ;
        }

        return view('company.main')->with('page', $getPage);
    }

what I'm looking for is a something like the pseudo example below. Where it will recursively get all nested sets with relations for every section found.

  $section->setRelation('children', $section->getDescendants()->toHierarchy())->with(['images','documents', 'menus']) ;
1 like
Estev's avatar

I was struggling with the same kind of problem and i finaly used this https://github.com/franzose/ClosureTable.

It's much more flexible than nested sets.

For your case getDescendantsTree() will give you the complete child tree from the user you query.

You can also get the complete tree with getTree()

Nixus's avatar
class One extends Model {
    public function children()
    {
        return $this->hasMany(self::class, 'parent_id');
    }

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

This way works very good.

4 likes
kyobul's avatar

Simpler, doing the same is :

class One extends Model {
    public function children()
    {
        return $this->hasMany(self::class, 'parent_id')->with('children');
    }
}
2 likes

Please or to participate in this conversation.