#はじめに
ページのカテゴリなどで使うデータをlaravel-nestedsetでネストで扱う方法を記載します。
・Laravel-nestedset 公式URL
https://github.com/lazychaser/laravel-nestedset
##環境
・PHP 8.0.1
・Laravel 8.40.0
##1. laravel-nestedのインストール
php composer.phar require kalnoy/nestedset:5.0.3
##2. マイグレーションファイルにnestedをセットする。
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('categories', function (Blueprint $table): void {
$table->increments('id');
$table->string('name');
// '_lft' / '_rgt' / 'parent_id' が追加される
$table->nestedSet();
});
}
マイグレーションを実行する
php artisan migrate:fresh
テーブルを確認する。「_lft」, 「_rgt」 「parent_id」 が追加される。
mysql> show columns from categories;
+-----------+------------------+------+-----+---------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+-------------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| _lft | int(10) unsigned | NO | MUL | NULL | |
| _rgt | int(10) unsigned | NO | | NULL | |
| parent_id | int(10) unsigned | YES | | NULL | |
+-----------+------------------+------+-----+---------+-------------------+
##3. カテゴリの登録
Category::create([
'name' => '大カテゴリ',
'children' => [
[
'name' => '中カテゴリ',
'children' => [
[ 'name' => '小カテゴリ' ],
],
],
],
]);
createを実行しデータを確認すると、以下のようなデータで登録される。
+------+------+-----------+----+--------------+
| _lft | _rgt | parent_id | id | name |
+------+------+-----------+----+--------------+
| 1 | 6 | NULL | 1 | 大カテゴリ |
| 2 | 5 | 1 | 2 | 中カテゴリ |
| 3 | 4 | 2 | 3 | 小カテゴリ |
+------+------+-----------+----+--------------+
以下のようにも登録が可能。
$parent = Category::create(['name' => '大カテゴリ']);
$children = Category::create(['name' => '中カテゴリ']);
$children->appendTo($parent)->save();
##4. データ取得について
大カテゴリーの子孫(descendants)をリスト型式で取得する。
$parent = Category::find(1); // 大カテゴリー(id=1)
$categories = $parent->descendants()->get(); // 中カテゴリー、小カテゴリーをリストで取得
dd($categories->toArray()); // 配列形式で表示
-- データ結果 --
array:3 [
0 => array:5 [
"id" => 2
"name" => "中カテゴリ"
"_lft" => 2
"_rgt" => 5
"parent_id" => 1
]
1 => array:15 [
"id" => 3
"name" => "小カテゴリ"
"_lft" => 3
"_rgt" => 4
"parent_id" => 2
]
]
カテゴリーの先祖(ancestors)をリストで取得する。
$small = Category::find(3); // 小カテゴリー(id=3)
$categories = $small->ancestors()->get(); // 大カテゴリー、中カテゴリーをリストで取得
dd($categories->toArray()); // 配列形式で表示
-- データ結果 --
array:2 [
0 => array:5 [
"id" => 1
"name" => "大カテゴリ"
"_lft" => 1
"_rgt" => 6
"parent_id" => null
]
1 => array:5 [
"id" => 2
"name" => "中カテゴリ"
"_lft" => 2
"_rgt" => 5
"parent_id" => 1
]
]
カテゴリーをツリー形式(ネスト)で取得する。
$tree = Category::get()->toTree(); // ツリー形式(ネスト)で取得
dd($tree->toArray()); // 配列形式で表示
-- データ結果 --
array:1 [
0 => array:6 [
"id" => 1
"name" => "大カテゴリ"
"_lft" => 1
"_rgt" => 6
"parent_id" => null
"children" => array:1 [
0 => array:6 [
"id" => 2
"name" => "中カテゴリ"
"_lft" => 2
"_rgt" => 5
"parent_id" => 1
"children" => array:1 [
0 => array:6 [
"id" => 3
"name" => "小カテゴリ"
"_lft" => 3
"_rgt" => 4
"parent_id" => 2
"children" => []
]
]
]
]
]
]
親カテゴリ(一番上位のカテゴリ)をリスト形式で取得する。
// カテゴリを登録
$parent = Category::create(['name' => '大カテゴリ']);
$parent2 = Category::create(['name' => '大カテゴリ2']);
$children = Category::create(['name' => '中カテゴリ']);
$children->appendTo($parent1)->save();
// 親カテゴリ(一番上位のカテゴリ)をリスト形式で取得する。
$categories = Category::first()->whereIsRoot()->get();
dd($categories->toArray()); // 配列形式で表示
-- データ結果 --
array:2 [
0 => array:5 [
"id" => 1
"name" => "大カテゴリ"
"_lft" => 1
"_rgt" => 2
"parent_id" => null
]
1 => array:5 [
"id" => 2
"name" => "大カテゴリ2"
"_lft" => 3
"_rgt" => 8
"parent_id" => null
]
]