@@ -62,9 +62,10 @@ Node has following relationships that are fully functional and can be eagerly lo
6262
6363### Inserting nodes
6464
65- Moving and inserting nodes includes several database queries, so __ transaction is
66- automatically started__ when node is saved. It is safe to use global transaction
67- if you work with several models.
65+ Moving and inserting nodes includes several database queries, so it is
66+ highly recommended to use transactions.
67+
68+ __ IMPORTANT!__ As of v4.2.0 transaction is not automatically started
6869
6970Another important note is that __ structural manipulations are deferred__ until you
7071hit ` save ` on model (some methods implicitly call ` save ` and return boolean result
@@ -217,20 +218,37 @@ in `$data`. By default, nodes aren't deleted.
217218
218219* In some cases we will use an ` $id ` variable which is an id of the target node.*
219220
220- #### Ancestors
221+ #### Ancestors and descendants
221222
222223Ancestors make a chain of parents to the node. Helpful for displaying breadcrumbs
223224to the current category.
224225
226+ Descendants are all nodes in a sub tree, i.e. children of node, children of
227+ children, etc.
228+
229+ Both ancestors and descendants can be eagerly loaded.
230+
225231``` php
226- // #1 Using accessor
227- $result = $ node->getAncestors() ;
232+ // Accessing ancestors
233+ $node->ancestors ;
228234
229- // #2 Using a query
230- $result = $node->ancestors()->get();
235+ // Accessing descendants
236+ $node->descendants;
237+ ```
238+
239+ It is possible to load ancestors and descendants using custom query:
231240
232- // #3 Getting ancestors by primary key
241+ ``` php
233242$result = Category::ancestorsOf($id);
243+ $result = Category::ancestorsAndSelf($id);
244+ $result = Category::descendantsOf($id);
245+ $result = Category::descendantsAndSelf($id);
246+ ```
247+
248+ In most cases, you need your ancestors to be ordered by the level:
249+
250+ ``` php
251+ $result = Category::defaultOrder()->ancestorsOf($id);
234252```
235253
236254A collection of ancestors can be eagerly loaded:
@@ -245,31 +263,6 @@ $categories = Category::with('ancestors')->paginate(30);
245263@endforeach
246264```
247265
248- #### Descendants
249-
250- Descendants are all nodes in a sub tree, i.e. children of node, children of
251- children, etc.
252-
253- ``` php
254- // #1 Using relationship
255- $result = $node->descendants;
256-
257- // #2 Using a query
258- $result = $node->descendants()->get();
259-
260- // #3 Getting descendants by primary key
261- $result = Category::descendantsOf($id);
262-
263- // #3 Get descendants and the node by id
264- $result = Category::descendantsAndSelf($id);
265- ```
266-
267- Descendants can be eagerly loaded:
268-
269- ``` php
270- $nodes = Category::with('descendants')->whereIn('id', $idList)->get();
271- ```
272-
273266#### Siblings
274267
275268Siblings are nodes that have same parent.
@@ -340,14 +333,20 @@ To get nodes of specified level, you can apply `having` constraint:
340333$result = Category::withDepth()->having('depth', '=', 1)->get();
341334```
342335
336+ __ IMPORTANT!__ This will not work in database strict mode
337+
343338#### Default order
344339
345- Each node has it's own unique ` _lft ` value that determines its position in the tree. If
346- you want node to be ordered by this value, you can use ` defaultOrder ` method on
347- the query builder:
340+ All nodes are strictly organized internally. By default, no order is
341+ applied, so nodes may appear in random order and this doesn't affect
342+ displaying a tree. You can order nodes by alphabet or other index.
343+
344+ But in some cases hierarchical order is essential. It is required for
345+ retrieving ancestors and can be used to order menu items.
346+
347+ To apply tree order ` defaultOrder ` method is used:
348348
349349``` php
350- // All nodes will now be ordered by lft value
351350$result = Category::defaultOrder()->get();
352351```
353352
@@ -357,8 +356,6 @@ You can get nodes in reversed order:
357356$result = Category::reversed()->get();
358357```
359358
360- ##### Shifting a node
361-
362359To shift node up or down inside parent to affect default order:
363360
364361``` php
@@ -448,17 +445,27 @@ after parent node. This is helpful when you get nodes with custom order
448445$nodes = Category::get()->toFlatTree();
449446```
450447
448+ Previous example will output:
449+
450+ ```
451+ Root
452+ Child 1
453+ Sub child 1
454+ Child 2
455+ Another root
456+ ```
457+
451458##### Getting a subtree
452459
453460Sometimes you don't need whole tree to be loaded and just some subtree of specific node.
454461It is show in following example:
455462
456463``` php
457- $root = Category::find($rootId);
458- $tree = $root->descendants->toTree($root);
464+ $root = Category::descendantsAndSelf($rootId)->toTree()->first();
459465```
460466
461- Now ` $tree ` contains children of ` $root ` node.
467+ In a single query we are getting a root of a subtree and all of its
468+ descendants that are accessible via ` children ` relation.
462469
463470If you don't need ` $root ` node itself, do following instead:
464471
@@ -692,7 +699,7 @@ MyModel::fixTree();
692699License
693700=======
694701
695- Copyright (c) 2016 Alexander Kalnoy
702+ Copyright (c) 2017 Alexander Kalnoy
696703
697704Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
698705
0 commit comments