Jak utworzyć zagnieżdżoną listę kategorii w Laravel?

Jak mogę utworzyć zagnieżdżoną listę kategorii w Laravel?

Chcę stworzyć coś takiego:

  • --- Php
  • ------ Laravel
  • --------- Wersja
  • ------------ V 5.7
  • --- Python
  • ------ Django
  • --- Ruby
  • ..........

Pola mojej tabeli kategorii to:

id | name | parent_id

Jeśli muszę dodać kolejną kolumnę jak głębokość lub powiedz mi coś, Proszę.

Używam poniższego kodu, ale myślę, że nie jest to najlepsze rozwiązanie. Poza tym nie mogę przekazać tej funkcji moim zdaniem.

function rec($id)
{
     $model = Category::find($id);
     foreach ($model->children as $chield) rec($chield->id);
     return $model->all();
}

function main () {
    $models = Category::whereNull('parent_id')->get();
    foreach ($models as $parent) return rec($parent->id);
}
Author: X 47 48 - IR, 2017-05-15

6 answers

Możesz zrobić model samo-referencyjny:

class Category extends Model {

    public function parent()
    {
        return $this->belongsTo('Category', 'parent_id');
    }

    public function children()
    {
        return $this->hasMany('Category', 'parent_id');
    }
}

I zrób relację rekurencyjną:

// recursive, loads all descendants
public function childrenRecursive()
{
   return $this->children()->with('childrenRecursive');
}

I zdobyć rodziców ze wszystkimi swoimi dziećmi:

$categories = Category::with('childrenRecursive')->whereNull('parent_id')->get();

Na koniec musisz po prostu iterować przez dzieci, dopóki dzieci nie będą zerowe. Zdecydowanie mogą wystąpić problemy z wydajnością, jeśli nie jesteś ostrożny. Jeśli jest to dość mały zbiór danych, który planujesz pozostać w ten sposób, nie powinien być problemem. Jeśli ma to być stale rosnąca lista, może mieć sens, aby mieć root_parent_id lub coś do odpytywania i składania drzewa ręcznie.

 27
Author: Alex Harris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-11 18:33:03

Jeśli ktoś potrzebuje lepszej odpowiedzi, sprawdź moją odpowiedź, pomogło mi, gdy miałem do czynienia z takim problemem.

   class Category extends Model {

     private $descendants = [];

     public function children()
        {
            return $this->subcategories()->with('children');
        }

     public function hasChildren(){
            if($this->children->count()){
                return true;
            }

            return false;
        }

     public function findDescendants(Category $category){
            $this->descendants[] = $category->id;

            if($category->hasChildren()){
                foreach($category->children as $child){
                    $this->findDescendants($child);
                }
            }
        }

      public function getDescendants(Category $category){
            $this->findDescendants($category);
            return $this->descendants;
        }
 }

I w Twoim kontrolerze po prostu przetestuj to:

$category = Category::find(1);
$category_ids = $category->getDescendants($category);

Spowoduje ID w tablicy wszystkich potomków Twojej kategorii, gdzie id=1. wtedy:

$products = Product::whereIn('category_id',$category_ids)->get();

Zapraszam =)

 2
Author: tokkerbaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-03 12:38:50

Ta funkcja zwróci tablicę drzewa:

function getCategoryTree($parent_id = 0, $spacing = '', $tree_array = array()) {
    $categories = Category::select('id', 'name', 'parent_id')->where('parent_id' ,'=', $parent_id)->orderBy('parent_id')->get();
    foreach ($categories as $item){
        $tree_array[] = ['categoryId' => $item->id, 'categoryName' =>$spacing . $item->name] ;
        $tree_array = $this->getCategoryTree($item->id, $spacing . '--', $tree_array);
    }
    return $tree_array;
}
 1
Author: グエン ヒューテイン,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-13 06:31:42

Szukając czegoś w tym obszarze chciałem podzielić się funkcjonalnością do uzyskania poziomu głębi dziecka:

    function getDepth($category, $level = 0) {
    if ($category->parent_id>0) {
        if ($category->parent) {
                $level++;
                return $this->getDepth($category->parent, $level);
            }
        }
       return $level;
    }
Może to komuś pomoże! Zdrowie!
 0
Author: nickRO87,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-14 10:35:26

Możesz rozwiązać ten problem w następujący sposób:

class Category extends Model
{
    public function categories()
    {
       return $this->hasMany(Category::class);
    }

    public function childrenCategories()
    {
       return $this->hasMany(Category::class)->with('categories');
    }

}

I zdobądź kategorię z takimi dziećmi:

Category::whereNull('category_id')
    ->with('childrenCategories')
    ->get();

Uwaga: Po prostu zmień nazwę kolumny parent_id na category_id

 0
Author: Amir Kaftari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-07 21:57:18

To również zadziałało:

Widok:

    $traverse = function ($categories) use (&$traverse) {
        foreach ($categories as $category) $traverse($cat->Children);
    };
    $traverse(array ($category));

Model:

public function Children()
{
    return $this->hasMany($this, 'parent');
}

public function Parent()
{
    return $this->hasOne($this,'id','parent');
}
 -1
Author: X 47 48 - IR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-27 10:53:27