Possible. From the little information you have given, I think your table only uses a parent pointer. Which isn't really sufficient for a nested set, as you don't have a children list, which means next() and previous() can never work properly, and since no list means no position, insert before and after operations will never work as well.
So either write a migration to convert your table format to something compatible with Nested Sets (the requirements are in the docs), or write your own custom implementation.
tree_id is not required, it is used when the table contains multiple trees.
But you can't just swap 'id' and 'parent' by 'left' and 'right', the two systems are completely different. You will have to create a migration that converts the table layout.
Create a function that accepts a parent id and a tree node object, and which runs a query to select all rows from the old table that have the given parent id. It then loops over the results, and for each result, adds the row as a child of the tree node object passed, then recurses with the id of the row as parent id, and the newly inserted child as tree node.
Then in the new table, you need to create a nested set root node, and when done, call your function with parent id 0, and the object of that root node as tree node.
This will convert your parent/child table to a nested set table.
In my opinion it's a bit pointless to use nestedset model in case of other table design, this is a overkill.
I decided to use original table schema for nestedset.
Hence 2 more questions:
1)
I saw that lots of queries are being run for a simple, 4 tree nested set. Any idea if I can cache the results forever and refresh them only while adding a new category? Or I rather should cache what I want to build with the tree (HTML list)?
2)
How can I sort the tree items?
I build the HTML ul from them like:
<ul>
<li>
Root
<ul>
<li>Children of root</li> <li>I want to be on the top</li> <li>I want to be second</li> </ul>
As for the sorting, the Fuel NestedSets architecture has a previous/next pointer design, which means every node has a fixed place in the tree. If you want to sort that, you need to fetch every branch of the tree individually, sort them, and store the result in a custom structure (as the sort would break the pointers).
See the picture in the docs for a visual on how the pointer system works.
If you want to minimize the interaction with the DB, you could look at the dump_tree() method, which can return the entire tree in a flat array or in an object tree structure, depending on your requirements.
Yeah? If you want the tree structure, you'll have to. I thought the question was "can I retrieve the tree so I can cache it"?
If you just want a flat list, you can also use $category->decendants()->get() which gives you all objects under the root with a single query. Obviously, that returns a flat list, so you need to put more effort in yourself if you actually want to use it.
btw, I checked the code for dump_tree(), and it does exactly that, which runs a single query per tree. So about which "same queries" are you exactly talking? That should should only run n+1 queries, where n is the number of trees in the table.
Your link confirms that, according to that output, you have 6 different trees in that table, so it runs 7 queries, one to get the list of tree id's, and one for each tree.
I did mention that, because your solution was to use dump_tree() method (to minimalize interaction with the DB) but it turns out that even when I use this the standard way which is:
foreach(Model_Category::forge()->roots()->get() as $category)
{
$category->children()->something[..]
}
It would return exact the same number of queries.
So, to make it clear, I can not cache the whole tree so I could then re-use it (to bypass n+1 queries)?
Btw. can I somehow dump tree of the whole table?
I'm currently having this trees:
Tree1
Child1
Child2
Child3
Child of child1
Tree2
Child1
Child2
Child3
Tree3
Child1
Child2
Child3
When I run Model_Category::forge()->roots()->get() I get the array with the size of the trees, however, I would like to get the output simiar to the dump_tree(). However, dump_tree() can only be run on tree-selected nodes so I have to select some tree in order to access it's children and so on. I would like to have exact the same array, but with childrens of all trees already.
I need this to generate the HTML unordered list of my trees, something like you did in this snippet: https://bin.fuelphp.com/snippet/view/HZ but, you're doing it for individual node and I would like to make it for all nodes, so they will be condensed within one <ul> like:
There is no "whole" tree, there are 6 different trees, which just happen to be stored in the same table?
So you have 1 query to get the id's of the trrees, and 1 query for each of the trees. making n+1. And as with any other object, you can use the Cache class to cache them, why not? Or do you mean something else with "cache"?
If you want them to be part of a single tree, you have to create it as such.
It looks like you have misunderstood the concept of multiple trees and the tree_id.
If you store multi-level menu's (for things like drop-downs and so), it is logical that each menu is a separate tree, as they are not related to each other, and you use them seperately.
If you look at for example the product category list in a webshop, it is usually used and displayed as a single tree, all info belongs together.
So if that is your intention, I would create a single tree, with a root node you only use as "anchor" (dummy if you will), and with all your main categories as children of that root node. And then write your HTML generator accordingly, so that it starts recursing with the root node, but don't include it in the output.