Создать древовидную структуру из двух таблиц - PullRequest
1 голос
/ 29 апреля 2020

Итак, моя проблема в том, что мне нужно построить дерево с данными из двух таблиц.

У меня есть следующие таблицы:

Category:

| id | parent_id | name           |
|----|-----------|----------------|
| 1  | null      | Category 1     |
| 2  | 1         | Category 1.1   |
| 3  | 2         | Category 1.1.1 |
| 4  | null      | Category 2     |
| 5  | 4         | Category 2.1   |
| 6  | null      | Category 3     |


Layer:

| id | category_id | name    |
|----|-------------|---------|
| 1  | 2           | Layer 1 |
| 2  | 2           | Layer 2 |
| 3  | 3           | Layer 3 |
| 4  | 4           | Layer 4 |
| 5  | 4           | Layer 5 |
| 6  | 5           | Layer 6 |

Модель моей категории:

class Category extends Model
{
    public function parent()
    {
        return $this->belongsTo('App\Category', 'parent_id');
    }

    public function childrens()
    {
        return $this->hasMany('App\Category', 'parent_id', 'id');
    }

    public function layers()
    {
        return $this->hasMany('App\Layer', 'category_id', 'id');
    }
}

Модель слоя:

class Layer extends Model
{
    public function category()
    {
        return $this->belongsTo('App\Category', 'category_id');
    }
}

Я использую следующую функцию для построения дерева категорий:

public function index()
{
    $categories = Category::all();
    $layers = Layer::all();

    return $this->buildTree($categories->toArray(), null);
}


function buildTree($categories, $parent_id)
{
    $categoriesTree = [];
    foreach ($categories as $category) {
        $category['folder'] = true;

         if ($category['parent_id'] == $parent_id) {
            $childrens = $this->buildTree($categories, $category['id']);
            if ($childrens) {
                $category['childrens'] = $childrens;
            }

            $categoriesTree[] = $category;
        }
    }

    return $categoriesTree;
}

Приведенная выше функция хорошо работает для категорий, и ответ :

  • Категория 1
    • Категория 1.1
      • Категория 1.1.1
  • Категория 2
    • Категория 2.1
  • Категория 3

Но я хочу добавить слои как дочерние элементы соответствующей категории, как показано ниже:

  • Категория 1
    • Категория 1.1
      • Категория 1.1.1
        • Слой 3
      • Слой 1
      • Слой 2
  • Категория 2
    • Категория 2.1
      • Слой 6
    • Слой 4
    • Слой 5
  • Категория 3

Каков наилучший способ сделать это?

1 Ответ

1 голос
/ 29 апреля 2020

Я предлагаю использовать отношение в вашей Категории модели с Layer моделью и готово загрузить ее. Таким образом, вы получите тот же результат, но с меньшими издержками на функцию buildTree, потому что Laravel выполняет большую часть работы:

Категория. php модель

class Category extends Model
{
    // ...

    public function layers()
    {
        return $this->hasMany(Layer::class);
    }

    // ...
}

В вашем контроллере :

public function index()
{
    $categories = Category::with('layers')->get();

    // ...
}

В результате получается такой массив:

eager loaded layers per category

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...