CakePHP1.2のTreeビヘイビア雑感

 引き続きCakePHPのver1.2新モジュールについて。
 v1.2からはビヘイビアという機能がサポートされています。コントローラ→コンポーネント、ビュー→ヘルパー、モデル→ビヘイビアといった感じでしょうか。モデルの振る舞い(behavior)を設定できるモジュールが作れるようになったみたいです。
 http://book.cakephp.org/ja/complete/27/developing-with-cakephp
あたりを参考にとりあえずv1.2デフォのTreeビヘイビアを試してみました。例えばブログのカテゴリのような階層構造を実装できるそうです。簡易self joinみたいなものですか?

規約

 parent_id・・・上の階層にあるレコードのid。int型
 lft・・・int型
 rght・・・int型
 が必須。lft、rghtという謎の値ですが、どうもグラフの評価に「変形プリオーダーツリー横断アルゴリズム」を採用しているよう。なんだそりゃ。
 

サンプルデータベース

CREATE TABLE `hierarchies` (
  `id` int(10) NOT NULL auto_increment,
  `parent_id` int(10) default NULL,
  `lft` int(10) default NULL,
  `rght` int(10) default NULL,
  `name` varchar(255) NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY  (`id`)
) ;
INSERT INTO `hierarchies` (`id`, `parent_id`, `lft`, `rght`, `name`) VALUES
(1, NULL, 1, 10, 'アメリカ'),
(2, 5, 3, 8, '自民党'),
(3, NULL, 15, 18, '社民党'),
(4, NULL, 11, 14, '民主党'),
(5, 1, 2, 9, '電通'),
(6, 2, 4, 5, '安部晋三'),
(7, 2, 6, 7, '公明党'),
(8, 3, 16, 17, 'フェミニスト');
(9, 4, 12, 13, '農民');

モデル

<?php
class Hierarchy extends AppModel{
    var $name = 'Hierarchy';
    var $actsAs = 'Tree';
}
?>

 ビヘイビアを呼び出すプロパティは$actsAsです。

コントローラ

<?php
class HierarchiesController extends AppController {
    var $name = 'Hierarchies';
    var $helpers = array('Html', 'Form');
    function index(){
        print_r($this->Hierarchy->generatetreelist(
            null, "{n}.Hierarchy.id", "{n}.Hierarchy.name")
        );
    }
}
?>

 generatetreelistメソッドはgeneratelistメソッドと同様にオブジェクトの中身を配列で返します。


 で、空のビュー(views/hierarchies/index.ctp)をつくって実行してやると、

Array ( 
 [1] => アメリカ
 [5] => _電通
 [2] => __自民党
 [6] => ___安部晋三
 [7] => ___公明党
 [4] => 民主党
 [9] => _農民
 [3] => 社民党
 [8] => _フェミニスト
)

 という素敵な階層構造を表示してくれます。


 さて、問題は前述のアルゴリズムにおけるlftとrghtの値ですが、今回のようにlftとrghtを手動で打ち込むのでは話になりません。というわけで、parent_idを打ち込んだ後、lftとrghtの空カラムを作っておけば自動的にlftとrghtを埋めてくれるrecoveryというメソッドがあるらしいのですが、未実装。


 まだ実用レベルには程遠いようです。


関連記事:CakePHP1.2のAuthコンポーネント雑感