creocoder / yii2-nested-sets

The nested sets behavior for the Yii framework.
Other
446 stars 129 forks source link

Possible `NestedSet::correctCachedOnMoveBetweenTrees()` bug #19

Closed ivanche closed 9 years ago

ivanche commented 10 years ago

Была такая иерархия:

- Радио(id=3,lft=1, rgt=2, lvl=1, root=3)
- Авто (id=4,lft=1, rgt=2, lvl=1, root=4)

Хочу такую:

- Авто (id=4,lft=1, rgt=4, lvl=1, root=4)
- - Радио(id=3,lft=2, rgt=3, lvl=2, root=4)

Но получаю вообще:

- Авто (id=4,lft=1, rgt=6, lvl=1, root=4)
- - Радио(id=3,lft=4, rgt=5, lvl=2, root=4)

После обновления страницы всё норм становится. Перемещаю методом $model->moveAsLast($parent). Кусок кода из контроллера

$save = $model->load(Yii::$app->request->post()) && $model->saveNode() !== false;

if ( ($parent = Yii::$app->request->post('Category', ['parent'=>false])['parent']) || $parent!==false ) {
    $transaction = Yii::$app->getDb()->beginTransaction();
    if ($save && $parent > 0) {
        $parent = $this->findModel($parent);
        $save = $model->moveAsLast($parent); //Здесь эта странность
    } elseif (!$model->isRoot()) {
        $save = $model->isNewRecord ? $model->makeRoot() : $model->moveAsRoot();
    }
    if ($save)
        $transaction->commit();
    else
        $transaction->rollBack();
}
ivanche commented 10 years ago

После дебагов выяснил, что в методе NestedSet::correctCachedOnMoveBetweenTrees() обе ноды прогоняются по 2 раза. То есть при первой итерации он правильно выстраивает, при второй не правильно. Как я дебагал и результат: https://gist.github.com/ivanche/cb84723c496f2d7f8758

creocoder commented 9 years ago

There is no more internal cache inside behavior for Yii 2 release version. Its planned, but behavior can be used without this with tree integrity garantee.