среда, 16 сентября 2009 г.

Cakephp TreeBehavior и отдельная ветка

Сегодня расскажу о замечательном свойстве TreeBehavior-a для Cakephp generatetreelist()
Как правило, он выдает большое дерево с подкатегориями и тому подобное.

чтобы использовать tree behavior, в вашей таблице должны быть хотя бы эти 3 поля:
parent_id, lft, rght

$this->Category->generatetreelist();
и все наше дерево готово!

Оказывается не все! а если я хочу не всю ветку, а начиная с id=5?
сразу скажу что варианты типа
$this->Category->generatetreelist(array('id'=>5));
Не прокатит. т.к. в этом случае он вернет только 'id'=5. а нам нужна ветка.

Ну что ж, пойдем дальше...
заменим $this->Category->generatetreelist(); на $this->Category->find('threaded');
этим мы ничего не изменили, а всего лишь вывели все поля, а не только key=>value

а для чего спросите Вы, здесь lft, rgth? странно. я сам долго не мог понять, а чем им id не понравился для сортировки?

как выяснилось, они вовсе не для сортировки.
пока у строк parent_id=0, т.е все они нулевого уровня, lft+1=rght
до того как Вы для какого нибудь элемента добавите дочерний.

Что же тут происходит? lft и rght продолжают нумерацию дальше, как ни в чем ни бывало, не смотря на то что это уже дочерние элементы.
А вот у родительского lft тот же самый, но вот rght = "последний дочерний rght"+1

и так приступим:
$prn = $this->Category->find('first',
array('conditions'=>array('id'=>5))
);
$out = $this->Category->find('threaded', array('conditions'=>array('Category.lft BETWEEN ? AND ?'=> array($prn['Category']['lft'], $prn['Category']['rght'])), 'order'=>'lft');

удачного приготовления :-)