cakephpで単一テーブルで階層化構造を作る

初めてのcakephp

概要

単一テーブルで階層化構造を作るときの方法です。

作る際には記述に主に二つの方法があるそうです。

一つ目はコントローラで"$this->ModelName->find('threaded');"と呼び出す方法。

二つ目にはモデルで"public $actsAs = array('Tree');"と指定して使用する方法です。

 

この二つの主な違いはテーブルの定義にあります。前者はテーブルにparent_idを定義するだけで動くのに対し、後者ではparent_idに加えてlft,rghtの二つのパラメータを定義してやる必要があります。後者ではデータごとの包含関係まで含めたモデル化なのでいろいろやれることが増えそうです。

しかし、lftとrghtを計算するのがめんどくさい(楽なアルゴリズム・プログラムあったら教えて欲しい)ので前者の"threaded"を用いて実装しました。

テーブル

"threaded"を用いた場合、モデルには特に何も書く必要はありません。

テーブル定義はこんな感じ

    create table tests(
	id int not null auto_increment primary key,
	test_id int,
	name varchar(50),
	parent_id int default 0,
	created datetime default null,
	modified datetime default null
);

ついでにテストデータ

  insert into tests(test_id,name,parent_id,created,modified) values
    (1000000,"fassion",null,now(),now()),
    (1010000,"mens",1,now(),now()),
    (1020000,"ladies",1,now(),now()),
    (2000000,"bag,shose",null,now(),now()),
    (2010000,"bag",4,now(),now())
   ;

既存のidの他に個別IDを降りたかったので"test_id"を定義してます。

コントローラ

コントローラではたったの2行でviewに送れちゃいます。

    $tree_test = $this->Test->find('threaded');
	$this->set("tests", $tree_test);

ビュー

簡単にprint_rをすると

    <?php print_r($yasu); ?>

↓結果↓

  Array ( [0] => Array 
    ( [Test] => Array 
      ( [id] => 1 
        [category_id] => 1000000 
        [name] => fassion 
        [parent_id] => 
        [created] => 2015-03-10 17:45:19 
        [modified] => 2015-03-10 17:45:19 
      ) 
      [children] => Array 
           ( [0] => Array 
                ( [Test] => Array 
                    ( [id] => 2 
                      [category_id] => 1010000 
                      [name] => mens 
                      [parent_id] => 1 
                      [created] => 2015-03-10 17:45:19 
                      [modified] => 2015-03-10 17:45:19 
                    ) 
                  [children] => Array ( ) 
                ) 
             [1] => Array 
                ( [Test] => Array 
                    ( [id] => 3 
                      [category_id] => 1020000 
                      [name] => ladies 
                      [parent_id] => 1 
                      [created] => 2015-03-10 17:45:19 
                      [modified] => 2015-03-10 17:45:19 
                    ) 
                  [children] => Array ( ) 
                ) 
            ) 
        ) 
            [1] => Array 
    ( [Test] => Array 
      ( [id] => 4 
        [category_id] => 2000000 
        [name] => bag,shose 
        [parent_id] => 
        [created] => 2015-03-10 17:45:19 
        [modified] => 2015-03-10 17:45:19 
      ) 
      [children] => Array 
            ( [0] => Array 
              ( [Test] => Array 
                 ( 
                   [id] => 5 
                   [category_id] => 2010000 
                   [name] => bag 
                   [parent_id] => 4 
                   [created] => 2015-03-10 17:45:19 
                   [modified] => 2015-03-10 17:45:19 
                   )
                [children] => Array ( )
            ) 
        )
      ) 
    )

(あぁ、改行めんど)

な感じで受け取れます。

foreach回したりして存分に楽しんでください。

参考等々

http://book.cakephp.org/1.3/ja/The-Manual/Core-Behaviors/Tree.html http://book.cakephp.org/2.0/ja/models/retrieving-your-data.html 2つ目の方を勉強したいなら:http://www.geocities.jp/mickindex/database/db_tree_ns.html