Scenario

情境:若有一個資料表 ProductType,裡面有 food, drinks, shoes 等項目。現在要改成巢狀的 ProductType,Schema 如下:

Schema

| id        | primary id       |
| --------- | ---------------- |
| parent_id | unsigned big int |
| --------- | ---------------- |
| name      | string           |

Result

原本的輸出資料:

[
	{
		id: 1,
		name: food
	}, {
		id: 2,
		name: drinks
	}, {
		id: 3,
		name: shoes
	},
]

要改成如下:

[
	{
		id: 1,
		name: food
		children: [
			{
				id: 2,
				name: drinks
			}
		]
	}, 
	{
		id: 3,
		name: shoes
		children: []
	},
]

Model

class ProductType
{
	// ...

	public function children()
	{
		return $this->hasMany(ProductType::class, 'parent_id', 'id')**->with('children')**;
	}
}

Migration

Schema::create('product_types', function (Blueprint $table) {
    $table->id();
    **$table->unsignedBigInteger('parent_id')->nullable();**
    $table->foreign('parent_id')->references('id')->on('product_types')->onDelete('cascade');
    $table->string('name');
});

Controller

public function index()
{
	return ProductType::with('children')**->whereNull('parent_id')**->get();
}

如此就能有期望的結果了!

[
  {
    "id": 1,
    "parent_id": null,
    "name": "food",
    "children": [
      {
        "id": 2,
        "parent_id": 1,
        "name": "dry",
        "children": [
          {
            "id": 4,
            "parent_id": 2,
            "name": "can",
            "children": []
          },
          {
            "id": 5,
            "parent_id": 2,
            "name": "souce",
            "children": []
          }
        ]
      },
      {
        "id": 3,
        "parent_id": 1,
        "name": "wet",
        "children": [
          {
            "id": 7,
            "parent_id": 3,
            "name": "drinks",
            "children": [
              {
                "id": 6,
                "parent_id": 7,
                "name": "milk",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "id": 8,
    "parent_id": null,
    "name": "glasses",
    "children": []
  }
]