Category Hierarchy Using Nested Set

456 views Asked by At

I am trying to create a category hierarchy using nested sets in Propel. I don't particularly care about the left/right stuff, I just want to be able to define a hierarchy.

I am having problems with propel complaining that a root node already exists with the given scope even though I am looking for an existing root node? I'm new to Propel and the nested set model so I'm really not sure what I'm doing wrong.

My table schema:

<table name="category">
    <column name="id" type="integer" primaryKey="true" autoIncrement="true"/>
    <column name="name" type="varchar" size="250" required="true" primaryString="true"/>

    <behavior name="nested_set">
        <parameter name="use_scope" value="true"/>
        <parameter name="scope_column" value="scope"/>
        <parameter name="left_column" value="left" />
        <parameter name="right_column" value="right"/>
        <parameter name="level_column" value="level"/>
    </behavior>

    <foreign-key foreignTable="category" onDelete="CASCADE" onUpdate="CASCADE">
        <reference local="scope" foreign="id"/>
    </foreign-key>
</table>

The function for creating the categories:

/**
 * Takes an array of category names. The first name is taken as 
 * the root category and then each name is a child of the preceding
 * name.
 */
function createCategories(array $names) {
    $categories = [];
    $root = CategoryQuery::create()
        ->filterByName($names[0])
        ->filterByLevel(0)
        ->findOneOrCreate();

    if($root->isNew()) {
        $root->save();
        $root->setScopeValue($root->getId());
    }

    $categories[0] = $root;

    foreach($names as $level => $name) {
        if($level == 0) {
            continue;
        }

        $category = CategoryQuery::create()
            ->filterByName($name)
            ->filterByScope($root->getScopeValue())
            ->findOneOrCreate();

        if($category->isNew()) {
            $category->insertAsFirstChildOf($categories[$level - 1]);
        }

        $categories[$level] = $category;
    }

    return $categories;
}
1

There are 1 answers

0
maddisoj On

The issue was with the definition of a root node. I assumed that a root node was defined as one where the level is 0. Looking at the generated code it in fact defines a root as one where it's left value is 1.

To correctly have the node defined as a root you can call:

$root->makeRoot()

This error then goes away.