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

panthro's avatar

Recursive relationship - set depth?

On a tag model I have a children relationship which recursively loads the polymorphic tags relations; this gives me every tag's child. A tag can have many tags, and a tag can belong to many tags.

public function tags()
{
        return $this->morphToMany(Tag::class, 'taggable');
}

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

I am wondering how I can limit the depth here? I have thought about doing something like this:

 public function children()
 {      
        return $this->tags()->with(implode('.', array_fill(0, 5, 'tags')));
}

The above would get 6 levels of tags.

I would appreciate any thoughts.

Please note, nested sets will not work with m2m relationships and https://github.com/staudenmeir/laravel-adjacency-list adjacency list package does not support m2m relationships either.

I'm also aware of efficiency issues. I plan on some caching.

0 likes
5 replies
rodrigo.pedra's avatar

I have thought about doing something like this...

Did you try it?

I usually go for closure tables for hierarchical data on SQL.

I am not aware of any PHP implementations as I usually implement them on the projects I use it (or copy from a project to other if it is for the same client). In this pattern you keep an auxiliary table that maps the hierarchies between your records and have a depth column.

Some articles in case you got interested:

And a book reference (from the author on first link above) where I got to know this pattern:

Unfortunately I cannot share the trait I wrote it for commissioned projects for clients.

Implementing it is not hard. Hardest parts are deleting or moving nodes. Inserting is easy enough and the great advantages are selecting tree paths and limiting depth.

panthro's avatar

@rodrigo.pedra thank you but as mentioned in my original posts, these packages do not work for many to many relationships.

rodrigo.pedra's avatar

@panthro Closure table does work for many to many relationships, including graph data with multiple roots (nodes without a parent).

I used it for a e-commerce project , where each sub-category could be allocated into may different categories.

Actually the closure table could be your pivot table, you just need to account to manage the depth column.

Maybe the blog examples in the links I sent before only show a traditional tree like structure, but the closure table pattern does work for this.

Adjacency list should work too, as there are graph implementations using this data structure. But maybe a different implementation is needed. For closure tables, you will need to tweak a bit of moving and deleting nodes to loop over possible root nodes, but selecting those are straightforward, what is left is to apply the same SQL queries in those links to each parent path.

As you have a graph of tags, you can search for packages that handle graphs instead of hierarchical data or tree ones.

1 like
rodrigo.pedra's avatar

@panthro one more thing: on my original post I asked if you have already tried your own suggestion.

Could you share your findings if that worked?

Please or to participate in this conversation.