Расширение ActiveRecord работа с деревом (Adjacency Lists)

Выкладываем свои наработки
Ответить
troublegum
Сообщения: 24
Зарегистрирован: 2010.12.17, 11:33
Контактная информация:

Расширение ActiveRecord работа с деревом (Adjacency Lists)

Сообщение troublegum » 2011.08.20, 15:44

Описание
Данное поведение позваляет работать с деревьями в бд по алгоритму Adjacency List.
Основное достоинство данного алгоритма простота управлением дерева и простота программной реализации.

Опции класса

parentAttribude - название атрибута модели который содержит id родительского узла (по умолчанию = "pid")
orderAttribude - название атрибута модели который содержит позицию узла (по умолчанию = "position")

Установка
Добавить в модель:

Код: Выделить всё

public function behaviors() 
{
    return array(
        'treebehavior' => array(
            'class' => 'yiiext.behaviors.model.treebehavior.ETreeBehavior',
            //    Настраиваем опции если необходимо
            'parentAttribude' => 'parent_id',
            'orderAttribude' => 'order'
        )        
    );
} 
Методы класса

children($criteria = null)
Получает всех детей данного узла по заданному критерию.
где $criteria - CDbCriteria

parent($criteria = null)
Получает родительский узел
где $criteria - CDbCriteria

path($criteria = null)
Получает путь от данного узла до корня дерева
где $criteria - CDbCriteria

branch($criteria = null, $depth = null, $returnAsNestedArrays = false)
Получает ветвь дерева относительно данного узла
где $criteria - CDbCriteria, $depth - глубина выборки, $returnAsNestedArrays - возвратить результат в виде вложенных массивов, а не списка

tree($criteria = null, $depth = null, $returnAsNestedArrays = false)
Получает дерево
где $criteria - CDbCriteria, $depth - глубина выборки, $returnAsNestedArrays - возвратить результат в виде вложенных массивов, а не списка

order(array $order)
Сортировка узлов
где $order - массив со значениями первичнычх ключей в порядке сортировки

FAQ
Что такое вложенный массив?
Вложенный массив это:

Код: Выделить всё

    
array(
        0 => узел 1,
        'children' => array(
            0 => узел 1.1
            'children' => array(
                0 => узел 1.1.1
                ...
            ) 
        )
    )
 
Вложенные массивы удобно использовать при построениии меню

Рекомендации
При большой вложенности дерева, рекомендуется использовать кеширование данных

TODO

Оптимизировать выборку данных
Каскадное удаление
level для узлов

Посмотреть на Github: https://github.com/troublegum/treebehavior или тут http://blog-programmista.ru/post/yii_ra ... lists.html
Последний раз редактировалось troublegum 2011.08.22, 11:46, всего редактировалось 6 раз.

Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение timlar » 2011.08.20, 15:52

Выкладывай на гитхабе. А то качать архив ради посмотреть как-то лень :)
Twitter: @timlar_ua

Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение Ekstazi » 2011.08.20, 16:03

Посмотрел. Код как-то неоптимально работает. (я про sql запросы).

troublegum
Сообщения: 24
Зарегистрирован: 2010.12.17, 11:33
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение troublegum » 2011.08.20, 16:08

Ekstazi писал(а):Посмотрел. Код как-то неоптимально работает. (я про sql запросы).
Очень интересно, а где именно?

troublegum
Сообщения: 24
Зарегистрирован: 2010.12.17, 11:33
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение troublegum » 2011.08.20, 16:41

timlar писал(а):Выкладывай на гитхабе. А то качать архив ради посмотреть как-то лень :)
Выложил тут: https://github.com/troublegum/Yii-exten ... aster/tree

Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение timlar » 2011.08.20, 17:43

troublegum писал(а):Выложил тут: https://github.com/troublegum/Yii-exten ... aster/tree
Спасибо. Посмотрю.
Twitter: @timlar_ua

Ekstazi
Сообщения: 1428
Зарегистрирован: 2009.08.20, 22:54
Откуда: Молдова, Бельцы
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение Ekstazi » 2011.08.20, 20:25

1)Ну вообщем то весь путь можно одним запросом выбрать
2) Не хватает поддержки поля level
3) не зватает возможности добавить потомка к родителю.
4) Неясно зачем makeCriteria - это как-то сильно раздуло комменты
5) Не хватает phpdoc.
6) Всех детей можно выбрать одним запросом используя join
7) Так же в некоторых СУБД есть connect by его бы тоже неплохо поддерживать.

Вот, для начала хватит.

Аватара пользователя
samdark
Администратор
Сообщения: 9175
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение samdark » 2011.08.20, 21:00

Выкладывать лучше в виде одна репа на расширение, чтобы потом, если что, можно было бы подключить к https://github.com/yiiext

troublegum
Сообщения: 24
Зарегистрирован: 2010.12.17, 11:33
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение troublegum » 2011.08.22, 10:15

Sam Dark писал(а):Выкладывать лучше в виде одна репа на расширение, чтобы потом, если что, можно было бы подключить к https://github.com/yiiext
Ок, переложил https://github.com/troublegum/treebehavior

Nafania
Сообщения: 1227
Зарегистрирован: 2011.01.31, 13:12

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение Nafania » 2011.09.08, 23:12

За расширение спасибо.
В строке 59 ошибка, вместо

Код: Выделить всё

$pk = $owner->primaryKey(); 
должно быть

Код: Выделить всё

$pk = $owner->getTableSchema()->primaryKey; 

troublegum
Сообщения: 24
Зарегистрирован: 2010.12.17, 11:33
Контактная информация:

Re: Расширение ActiveRecord работа с деревом (Adjacency List

Сообщение troublegum » 2011.09.10, 10:32

Nafania писал(а):За расширение спасибо.
В строке 59 ошибка, вместо

Код: Выделить всё

$pk = $owner->primaryKey(); 
должно быть

Код: Выделить всё

$pk = $owner->getTableSchema()->primaryKey; 
Ок. Спасибо учту )

Ответить