# Creating menu with tree behavior

**URL:** <https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249>\
**Category:** Need Help\
**Created:** [May 4, 2016, 2:48pm UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249 "2016-05-04T14:48:10Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![artnos](https://avatars.discourse-cdn.com/v4/letter/a/eb8c5e/32.png) [@artnos](https://discourse.cakephp.org/u/artnos)\
**Post date:** [May 4, 2016, 2:48pm UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/1 "2016-05-04T14:48:10Z")

</div>

I have a table with a parent\_id, i am trying to build a menu system, that chains with a recursive function

id | parent\_id | title | url  
1 0 home  
2 1 about  
3 2

cake console generated

//Menus Table  
public function initialize(array $config){

```
   $this->belongsTo('ParentMenus', [
        'className' => 'Menus',
        'foreignKey' => 'parent_id'
    ]);

    $this->hasMany('ChildMenus', [
        'className' => 'Menus',
        'foreignKey' => 'parent_id'
    ]);

 public function buildRules(RulesChecker $rules){
    $rules->add($rules->existsIn(['parent_id'], 'ParentMenus'));
    return $rules;
  }

```

Which works great but the top menu item I give it a parent \_id of 0 which doesn’t save because it doesn’t exist. Is there a way i can allow 0? I am creating button controls to allow being able to move up and down and rearrange the menu

---

<div class="post-metadata">

**Author:** ![mo86](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/mo86/32/92_2.png) [@mo86](https://discourse.cakephp.org/u/mo86)\
**Post date:** [May 4, 2016, 9:32pm UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/2 "2016-05-04T21:32:25Z")

</div>

I can only advise you to use the Tree Behaviour. This also gives you the possibility to handle more than 2 menulevels 🙂  
[http://book.cakephp.org/3.0/en/orm/behaviors/tree.html](http://book.cakephp.org/3.0/en/orm/behaviors/tree.html)

---

<div class="post-metadata">

**Author:** ![artnos](https://avatars.discourse-cdn.com/v4/letter/a/eb8c5e/32.png) [@artnos](https://discourse.cakephp.org/u/artnos)\
**Post date:** [May 5, 2016, 12:44am UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/3 "2016-05-05T00:44:45Z")

</div>

thank you i didnt know cake had something built in i will look into it

---

<div class="post-metadata">

**Author:** ![artnos](https://avatars.discourse-cdn.com/v4/letter/a/eb8c5e/32.png) [@artnos](https://discourse.cakephp.org/u/artnos)\
**Post date:** [May 5, 2016, 12:52am UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/4 "2016-05-05T00:52:37Z")

</div>

do u know what this concept is called outside of cake parent\_id lft right so i can read up, i learn this in college but forgot

---

<div class="post-metadata">

**Author:** ![raul338](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/raul338/32/69_2.png) [@raul338](https://discourse.cakephp.org/u/raul338)\
**Post date:** [May 5, 2016, 1:34am UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/5 "2016-05-05T01:34:37Z")

</div>

Its called trees.

another workaround that i used in the past is to set parent\_id to NULL when is a top menu. It should work with cake

---

<div class="post-metadata">

**Author:** ![artnos](https://avatars.discourse-cdn.com/v4/letter/a/eb8c5e/32.png) [@artnos](https://discourse.cakephp.org/u/artnos)\
**Post date:** [May 5, 2016, 1:51am UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/6 "2016-05-05T01:51:40Z")

</div>

i did that NULL as parent but i ran into another issue i couldnt do a query find parent ID equal to NULL it returned nothing

also another question this tree system what dors lft and right represent? the nodes above and below them? and if yes if its under the parent item does that mean left is NULL or the parent id and left are the same

hopefully that makes sense thank you

---

<div class="post-metadata">

**Author:** ![raul338](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/raul338/32/69_2.png) [@raul338](https://discourse.cakephp.org/u/raul338)\
**Post date:** [May 5, 2016, 2:04am UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/7 "2016-05-05T02:04:09Z")

</div>

You need to pass IS … like this  
`$query->where(["parent_id IS" => null]);`

And lft and rgt are the left and rigth node (All nodes sharing the same parent\_id can be ordered using that columns)

---

<div class="post-metadata">

**Author:** ![jeremyharris](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/jeremyharris/32/66_2.png) [@jeremyharris](https://discourse.cakephp.org/u/jeremyharris)\
**Post date:** [May 5, 2016, 3:35pm UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/8 "2016-05-05T15:35:27Z")

</div>

Specifically, the algorithm is called MPTT (Modified Preorder Tree Traversal). There’s a good article explaining how it works here: [http://www.sitepoint.com/hierarchical-data-database-2/](http://www.sitepoint.com/hierarchical-data-database-2/)

---

<div class="post-metadata">

**Author:** ![markstory](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/markstory/32/182_2.png) [@markstory](https://discourse.cakephp.org/u/markstory)\
**Post date:** [May 5, 2016, 7:23pm UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/9 "2016-05-05T19:23:52Z")

</div>

> [@artnos](#):
>
> do u know what this concept is called outside of cake parent\_id lft right so i can read up, i learn this in college but forgot

It is called Modified Preorderd Tree Traversal or MPTT. [Sitepoint](http://www.sitepoint.com/hierarchical-data-database-2/) has a good overview on how it works at the schema/DB level.

---

<div class="post-metadata">

**Author:** ![mo86](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/mo86/32/92_2.png) [@mo86](https://discourse.cakephp.org/u/mo86)\
**Post date:** [May 6, 2016, 11:26am UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/10 "2016-05-06T11:26:32Z")

</div>

its called “nested sets”

---

<div class="post-metadata">

**Author:** ![ADmad](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/admad/32/20_2.png) [@ADmad](https://discourse.cakephp.org/u/ADmad)\
**Post date:** [May 14, 2016, 8:23am UTC](https://discourse.cakephp.org/t/creating-menu-with-tree-behavior/249/11 "2016-05-14T08:23:10Z")

</div>

You can use the `TreeHelper` available in [https://github.com/ADmad/cakephp-tree](https://github.com/ADmad/cakephp-tree) to easily generate menus for models using `TreeBehavior` or nested dataset fetched using `find('threaded')`.
