はじめに。
こんばんは。
かんたんですが、ツリー構造を持っているmodelのリレーションを扱うものがあったので、備忘録として残しておきます。
本題
以下のようなテーブルがあるとします。
CREATE TABLE `categories` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `parent_id` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
今回、自分の子供の件数を取得したいという要件がありまして、 hasMany
で取れるのかな?と思ってやってみました。
Model
<?php namespace App\Models; use Illuminate\Database\Eloquent\Relations\HasMany; class Category extends Model { public function children(): HasMany { return $this->hasMany(self::class, 'parent_id', 'id'); } }
取得側
<?php namespace App\Http\Controllers\Actions; use App\Models\Category; class GetCategoryAction extends Model { public function __invoke() { $categories = Category::query() ->withCount(['children']) ->paginate(); dd(array_map(static fn(Category $category) => $category->toArray(), $categories->items())); } }
結果は以下のようにとれます。
^ array:2 [▼ 0 => array:3 [▼ "id" => 1 "name" => "XXXXXX" "children_count" => 1 ] 1 => array:3 [▼ "id" => 2 "name" => "xxxxx" "children_count" => 0 ] ]
終わりに
循環参照にだけ気をつける必要がありますが、かんたんにこんな事できるの、いいですね。
現場からは以上です。