Shlop
@Shlop
Full Stack Developer (PHP/Laravel/JavaScript)

Правильно ли добавлять свойство в объект модели таким образом?

Здравствуйте, у меня есть модель Category, у одной категории могут быть подкатегории, поэтому в модели есть метод children.
Метод children в модели
public function children()
{
   return $this->hasMany('App\Models\Admin\Category','parent_id');
}

И сейчас мне нужно построить дерево категорий но строю я не с помощью with и рекурсии, а просто получаю все категории одним запросом, и потом стою дерево.
Метод построения дерева
private static function makeTree($items, $parentId)
{
    $tree = collect();
    if(is_array($items) && isset($items[$parentId])) {
        foreach ($items[$parentId] as $item) {
                $item->children = self::makeTree($items, $item->id); //$item - тут объект категории
                $tree->push($item);
         }
     }
     else {
            return collect();
     }
     return $tree;
}

Вопрос в том что правильно ли делать так:
$item->children = self::makeTree($items, $item->id);

В Debugbar это выглядит вот так:
5e8ca48cc1c99350938173.png
Подскажите пожалуйста правильно ли это, заранее благодарю за ответ.
  • Вопрос задан
  • 174 просмотра
Решения вопроса 2
@Vitalionus
А почему не правильно то? Все работает логично. Можешь конечно tree пакет прикрутить, что бы не писать свой велосипед
Вот этот думаю один из удобных и простых, почти ничего делать не нужно просто добавить наслодование и указать ключи родителя
https://github.com/lazychaser/laravel-nestedset
Индексы еще в базе добавь обязательно для оптимизации выборки
Ответ написан
AmdY
@AmdY
PHP и прочие вебштучки
'App\Models\Admin\Category' - так вы потеряете данные при рефакторингах, лучше использовать \App\Models\Admin\Category::class или в вашем случае self::class
Зачем вам статический метод, если вы его дергаете из себя, то логично делать $this->makeTree()
Если у вас дерево ограниченной вложенности (обычно меньше 2-3 уровня), то достаточно воспользоваться дот нотацией в with
$categories->with('children', 'children.children', 'children.children.children');
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@jazzus
А почему с with нельзя? Там же parent with children все стыкуется. Если правильно понял задачу то можно так
Category::parents()
        ->with('children')
        ->get();

// в Category
public function children()
{
  return $this->hasMany(self::class, 'parent_id');
}

public function scopeParents($query)
{
    return $query->whereNull('parent_id');
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы