Laravelでカテゴリーツリーを構築する

ネストされたカテゴリーツリーをbaumで構築する方法

インストール

baumを利用してLaravel 4のEloquent ORMを拡張してツリータイプのデータ構造を生成します。

baumのページで使い方のマニュアルを確認することが出来ます。

etrepat/baum GitHub

composer.jsonに追記した上で

"require": {
  "laravel/framework": "4.2.*",
  "baum/baum": "~1.0"
},

アップデートします。

composer update

app/config/app.php

のproviders配列に

‘Baum\BaumServiceProvider’,

を追記すればbaumが利用可能な状態になります。

カテゴリーテーブルの構築

baumの用途はカテゴリーツリーに限らず、ネスト化したコメントデータなどにも利用可能ですが、本記事ではカテゴリーテーブルを定義して、最終的にツリー形式のデータ構造を生成してみます。

以下のコマンドを実行すると、

php artisan baum:install category

app/models/Category.php
app/database/migrations/2014_11_21_094306_create_categories_table.php

ModelとMigrationファイルが自動生成されます。

今回は、Modelファイルは自動生成されたままの状態で、Migrationファイルを以下のように編集しました。

public function up() {
  Schema::create('categories', function(Blueprint $table) {
    $table->increments('id');
    $table->integer('parent_id')->nullable()->index();
    $table->integer('lft')->nullable()->index();
    $table->integer('rgt')->nullable()->index();
    $table->integer('depth')->nullable();
    $table->string('name', 255);
    $table->string('slug', 255);
    $table->timestamps();
 });
}

デフォルトの状態にslugフィールドを設定するように変更してみました。

  • nameフィールドがカテゴリー名
  • slugフィールドがカテゴリーURL

といったイメージです。

php artisan migrate

上のコマンドを実行すれば、データベースにcategoriesテーブルが定義されます。

管理系インタフェースの使い方

REPLの起動

テーブルを作成することが出来たので、カテゴリーデータを挿入してみます。Laravelに備わっているREPLタイプのコマンドラインからデータを追加するLaravelのコードを実行します。

php artisan tinker

ルートノードの作成

カテゴリーのルートノードを追加します。

$root = Category::create(['name' => 'Root', 'slug' => 'root']);

データベースにルートカテゴリーが挿入されていることが確認できます。

ノードの削除

$root->delete();

削除する必要がある場合は、上のコマンドで削除することが可能です。

子ノードの作成

ルートノードの子ノードを作成します。カテゴリー階層的には最初の階層になります。

$child1 = $root->children()->create(['name' => 'ホームページ', 'slug' => 'homepage']);

子ノードの子ノードを作成

サブカテゴリー(第二階層)を作成します。

$child2 = $child1->children()->create(['name' => 'ホームページビルダー', 'slug' => 'homepage-builder']);

取得系インタフェースの使い方

シンプルな例

REPLでカテゴリーデータを作成したので、カテゴリーデータを取得します。

$node = Category::where('slug', '=', 'homepage')->first();
		
foreach($node->getDescendants() as $descendant) {
  var_dump($descendant->name);
}

上のコードでホームページカテゴリーのサブカテゴリーを取得出来ます。

ネスト化したデータ構造

toHierarchy()を利用して階層化されたデータ構造でカテゴリー情報を取得することが可能です。

$tree = Category::where('name', '=', 'Root')->first()->getDescendantsAndSelf()->toHierarchy();

$treeには階層化されたオブジェクトが返されます。以下のコードで配列に変換することが出来ます。

var_dump(json_decode(json_encode($tree), true));

データを確認すると、childrenキーでデータが階層化されていることが確認できます。

ネスト化されたツリー構造のデータを生成するライブラリとして、lazychaser/laravel-nestedset GitHubもあります。

Webエンジニアブログにコメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Laravelでカテゴリーツリーを構築するの記事にコメントを投稿