PHPackages                             theoluirard/tree-structured-relation - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. theoluirard/tree-structured-relation

ActiveLibrary[Database &amp; ORM](/categories/database)

theoluirard/tree-structured-relation
====================================

A package that adds a trait to the Laravel Model class and extends the Laravel Relation class with two new types of relations.

v1.2.3(5mo ago)018[1 PRs](https://github.com/theoLuirard/tree-structured-relation/pulls)MITPHPPHP &gt;=7.3

Since Feb 12Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/theoLuirard/tree-structured-relation)[ Packagist](https://packagist.org/packages/theoluirard/tree-structured-relation)[ RSS](/packages/theoluirard-tree-structured-relation/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (2)Versions (8)Used By (0)

Tree Structured Relation
========================

[](#tree-structured-relation)

This package provides a way to manage tree-structured data relations in your application

Features
--------

[](#features)

- Easy to integrate
- Allow to retrieve direct children and parent and also all the descendant of one node or all the predecessors of one node
- Lightweight and efficient
- Configurable

Installation
------------

[](#installation)

To install the package, use the following command:

```
composer require theoluirard/tree-structured-relation
```

What to expects
---------------

[](#what-to-expects)

This packages define a trait that you can add on your model class definition. It defines for the model some relation and method to retrieve children and parents. You can also retrieve easily all ancestors and descendant for a given node.

### Integrity is ensure by referencing the parent id

[](#integrity-is-ensure-by-referencing-the-parent-id)

When a node is created, it references the ID of its parent node (null if it's a root node). This ensures the integrity of the tree structure by maintaining a clear parent-child relationship. If a parent node is deleted, all its child nodes can be easily identified and handled accordingly. This reference mechanism helps in maintaining the consistency and integrity of the hierarchical data.

### An explicit path option is provided

[](#an-explicit-path-option-is-provided)

Having the path is nice for querying easily but for a human eye it could be a bit unreadable. You could add an explicit path column (so a second path property) that is based on more human readable value of your model

### Reading is done using the path

[](#reading-is-done-using-the-path)

**We use materialized path method to retrieve easily descendant and ancestors**
-------------------------------------------------------------------------------

[](#we-use-materialized-path-method-to-retrieve-easily-descendant-and-ancestors)

The **Materialized Path** method is a way of storing hierarchical data (like a tree structure) in a relational database using a **single table**, where each row represents a node in the hierarchy. It is an alternative to other methods like **Adjacency List**, **Nested Sets**, and **Closure Table**.

---

### **How Materialized Path Works**

[](#how-materialized-path-works)

Each node stores its **full path** from the root, typically as a string, instead of just a reference to a parent node. This makes querying hierarchical relationships efficient.

### **Table Structure**

[](#table-structure)

A typical table might look like this:

idnameparent\_idpathexplicit\_path1RootNULL/1/Root2A1/1/2/Root/A3B1/1/3/Root/B4A12/1/2/4/Root/A/A15A22/1/2/5/Root/A/A26B13/1/3/6/Root/B/B1Here:

- The `parent_id` ensures the integrity of the hierarchy
- The `path` column stores the full hierarchical path.
- The `explicit_path` column stores a human readable path
- The delimiter (`/` in this case) separates different levels of the hierarchy.

---

**Advantages of Materialized Path**
-----------------------------------

[](#advantages-of-materialized-path)

✅ **Fast subtree retrieval** (single query using `LIKE`).
✅ **Efficient insertions and deletions** (no need to update sibling nodes).
✅ **Easier to understand compared to Nested Sets.**
✅ **Good indexing support** with `VARCHAR` paths.

---

**Disadvantages**
-----------------

[](#disadvantages)

❌ **Path Updates Can Be Expensive** – Moving a node requires updating all descendant rows.
❌ **Limited Depth Handling** – If stored as `VARCHAR`, a very deep hierarchy can cause storage issues.
❌ **Indexing Constraints** – Indexing on a variable-length path column can be inefficient in large datasets.

---

**When to Use Materialized Path?**
----------------------------------

[](#when-to-use-materialized-path)

- When you need **fast subtree queries**.
- When insertions and deletions are frequent, but moves are rare.
- When your hierarchy is not extremely deep.

If you need **frequent node moves** or a **very large tree**, you might consider **Closure Tables** instead.

---

Configuration
-------------

[](#configuration)

### Add the trait to your model

[](#add-the-trait-to-your-model)

Simply add the trait to your model definition

```
