Yii Framework Forum: Nested set - Yii Framework Forum

Jump to content

  • (4 Pages)
  • +
  • « First
  • 2
  • 3
  • 4
  • You cannot start a new topic
  • You cannot reply to this topic

Nested set Nested set behavior for AR models Rate Topic: ***** 4 Votes

#61 User is offline   Boaz 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 367
  • Joined: 23-January 11

Posted 23 September 2012 - 04:03 PM

View PostBoaz, on 20 September 2012 - 02:50 PM, said:

Hi,

Similar to the curiosity raised in this comment on this thread, I'd also be happy to know why there is the 'root' and 'level' columns in the schema. AFAIK, they are not strictly needed in nested set implementation. Is that for performance enhancement?

I've looked at the couple of resources linked in the mentioned comment: the first is a 404 now and the second doesn't answer the question as well (though I've skimmed it).

Thanks!
Boaz.


Replying on my own post for the sake of others after getting half the answer here:
'root' column is a sort of foreign key, but to the same table, and it is used to relate the record to its root record in the tree represented in the relational table.
My thoughts: probably for performance reasons, avoiding traversing the entire tree with multiple queries, in case it is desired and all we have in our hands is a leaf down its structure.
Therapeutic PHP sessions My LinkedIn Profile
0

#62 User is offline   Boaz 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 367
  • Joined: 23-January 11

Posted 16 October 2012 - 02:54 AM

View Postjohonunu, on 15 September 2012 - 12:58 PM, said:


=============================
ROOT (ROOT)
--- HOME (LEAF)
--- NEWS (LEAF)
--- ABOUT (LEAF)
--- PORTFOLIO (LEAF)
--- --- WEBSITES (LEAF)
--- --- APPLICATIONS (LEAF)
--- SERVICES (LEAF)
=============================

I am using this at the moment, but I don't like to have page "Root" that don't get any use.

Thanks ;)


To the best of my knowledge what you're doing (above) is the only way to do it.
Nested set is a way to store a single tree information in SQL tables. The fact that the behavior class supports several trees in the same table is a nice add on, but nested set in theory has nothing to do with ordering of several roots.
I guess that going with what you already did or adding your own logic for ordering of roots is the way to go and there's no support for that in this extension, or from the the theoretical point of view.
Therapeutic PHP sessions My LinkedIn Profile
0

#63 User is offline   Boaz 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 367
  • Joined: 23-January 11

Posted 16 October 2012 - 03:00 AM

I have this tree:


Root
- child A
- child B
  -  child BA
  -  child BB


I need/want to move child BA and BB to upper level, meaning to be children of ROOT and to delete child B afterwards.

My problem is with the first two 'moves'. I cannot seem to move them since I use $childBA->moveAfter($ROOT) and this throws an exception telling me that "The target node should not be root". I also took a look at insertAfter() but this method is for new records only, yet child BA and child BB already exists.

How do I accomplish this?
Thanks!

EDIT: apparently, my usage was incorrect. moveAfter() requires the first parameter, $target, to be the destined brother to the node we're moving, not its destined parent.
Indeed I'm unable to use moveAsLast() (though I didn't really test it) since it will fail with the mentioned error, but using moveAfter() is possible and working.

This post has been edited by Boaz: 16 October 2012 - 03:37 AM

Therapeutic PHP sessions My LinkedIn Profile
0

#64 User is offline   yiibie 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 20
  • Joined: 06-July 12

Posted 02 November 2012 - 03:27 AM

Is it possible to use the NestedSet AR in a with(), so that it loads the complete hierarchy?
Example:
AR Product BELONGS_TO Category
AR Category (with NestedSet behavior) HAS_MANY Products

Now I want to get the product with ID = 1 together with its complete category hierarchy?
The way in single queries is:
$p = Product.findByPk(1);
$cat = Category.findByPk($p->cat_id);
$hierarchy = $cat->ancestors()->findAll();

Is there a better way or at least sth. like ancestorsById() ?
0

#65 User is offline   florin p 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 25-September 11

Posted 02 December 2012 - 02:18 PM

Hi,

I have a similar question as the one mentioned above, basically I have 2 models, categories and products. In category model I use nested set behavior to generate the categories tree.

Currently my product model criteria looks like:
$criteria = new CDbCriteria;
                $criteria->with = array(
                    'categories' => array(
                        'on' => 'categories.id=:catId',
                        'joinType' => 'INNER JOIN',
                        'params' => array(':catId' => $catId),
                    ),
            );



How could I fetch all the products from descendants categories of the current category? i tried to google but so far no solution fit my needs :(
Please help!
0

#66 User is offline   Wiseon3 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 14-February 11

Posted 03 December 2012 - 10:28 AM

View Postflorin p, on 02 December 2012 - 02:18 PM, said:

Hi,

I have a similar question as the one mentioned above, basically I have 2 models, categories and products. In category model I use nested set behavior to generate the categories tree.

Currently my product model criteria looks like:
$criteria = new CDbCriteria;
                $criteria->with = array(
                    'categories' => array(
                        'on' => 'categories.id=:catId',
                        'joinType' => 'INNER JOIN',
                        'params' => array(':catId' => $catId),
                    ),
            );



How could I fetch all the products from descendants categories of the current category? i tried to google but so far no solution fit my needs :(
Please help!

I did something like this:
        $categoryModel = ErpProductCategory::model()->findByPk($id);
        $model = new ErpProduct('search');
        $model->unsetAttributes();  // clear any default values
        if (isset($_POST['ErpProduct']))
        {
            $model->attributes=$_POST['ErpProduct'];
        }

        // get descendants of current category
        $criteria = $categoryModel->descendants()->getDbCriteria();
        // get current model alias
        $alias = $model->getTableAlias();
        // add conditions for category
        $model->getDbCriteria()->mergeWith($criteria);
        // also get the products directly under the category, not only those from subcategories
        $model->getDbCriteria()->addCondition($categoryModel->getTableAlias().'.id = ' . $categoryModel->id, 'OR');
        // restore the correct alias
        $model->getDbCriteria()->alias = $alias;

        $this->render('index', array(
            'dataProvider' => $model->search(),
            'categoryModel' => $categoryModel,
        ));

The resulting query would be something along the lines (I stripped a lot of code since I'm doing a more complex query with status checks for products and parent categories):
SELECT `erpp`.*, `erppc`.*
FROM `erp_product` `erpp` 
LEFT OUTER JOIN `erp_product_category` `erppc` ON (`erpp`.`category_id`=`erppc`.`id`) 
WHERE (((`erppc`.`lft`>6 AND `erppc`.`rgt`<9) AND (`erppc`.`root`=:ycp1)) OR (erppc.id = 3)) ORDER BY `erppc`.`lft` LIMIT 10. Bound with :ycp1='1'

1

#67 User is offline   florin p 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 25-September 11

Posted 03 December 2012 - 11:08 AM

View PostWiseon3, on 03 December 2012 - 10:28 AM, said:

I did something like this:
        $categoryModel = ErpProductCategory::model()->findByPk($id);
        $model = new ErpProduct('search');
        $model->unsetAttributes();  // clear any default values
        if (isset($_POST['ErpProduct']))
        {
            $model->attributes=$_POST['ErpProduct'];
        }

        // get descendants of current category
        $criteria = $categoryModel->descendants()->getDbCriteria();
        // get current model alias
        $alias = $model->getTableAlias();
        // add conditions for category
        $model->getDbCriteria()->mergeWith($criteria);
        // also get the products directly under the category, not only those from subcategories
        $model->getDbCriteria()->addCondition($categoryModel->getTableAlias().'.id = ' . $categoryModel->id, 'OR');
        // restore the correct alias
        $model->getDbCriteria()->alias = $alias;

        $this->render('index', array(
            'dataProvider' => $model->search(),
            'categoryModel' => $categoryModel,
        ));

The resulting query would be something along the lines (I stripped a lot of code since I'm doing a more complex query with status checks for products and parent categories):
SELECT `erpp`.*, `erppc`.*
FROM `erp_product` `erpp` 
LEFT OUTER JOIN `erp_product_category` `erppc` ON (`erpp`.`category_id`=`erppc`.`id`) 
WHERE (((`erppc`.`lft`>6 AND `erppc`.`rgt`<9) AND (`erppc`.`root`=:ycp1)) OR (erppc.id = 3)) ORDER BY `erppc`.`lft` LIMIT 10. Bound with :ycp1='1'



Thanks a lot I got it working :)
0

#68 User is offline   MrBinWin 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 25-February 13

Posted 08 July 2013 - 07:34 AM

Hello. There is an error in "Useful code (Non-recursive tree traversal)" block:
http://www.yiiframew...tedsetbehavior/

in line: for($i=$level-$model->level;$i;$i--)
correct code: for($i=$level-$category->level;$i;$i--)


Could you fix it, please.
Thank you.
0

#69 User is offline   leo4all 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 30
  • Joined: 01-April 13
  • Location:Alajuela, Costa Rica

Posted 15 July 2013 - 04:14 PM

Hi am looking around some help.

What If I have products and category related (fk), and I need to delete categories?
what happen with the related category_id on products table?

Sorry my English or if its bad formulated the question.
0

#70 User is offline   CoderK 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 16
  • Joined: 13-June 13

Posted 28 July 2013 - 11:05 AM

How do I move one node and all of its children to a new root?
0

Share this topic:


  • (4 Pages)
  • +
  • « First
  • 2
  • 3
  • 4
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users