skip to Main Content

I have created a logic to create unlimited categories, but I want to show the main category and its subcategories with the select box, but I can print only limited to a certain extent.

category db:
id - name - parent_id

category model relationships:

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

category controller:

public function categoryTree(): JsonResponse
    {
        $categories = Categories::all();
        $categoriesArr = [];
        foreach ($categories as $category){
            if ($category->parent_id === 0){
                $categoriesArr[] = [
                    'title' => $category->name,
                    'value' => $category->id,
                ];
                continue;
            }
            $categoriesArr[] = [
                'title' => $category->parent->parent_id !== 0 ? $category->parent->parent->name.' > '.$category->parent->name.' > '.$category->name : $category->parent->name.' > '.$category->name,
                'value' => $category->id,
            ];
        }

        return response()->json($categoriesArr);
    }

Now I’m getting the following output:

[
    {
        "title": "Real Estate",
        "value": 1
    },
    {
        "title": "Vehicle",
        "value": 2
    },
    {
        "title": "Vehicle > Car",
        "value": 3
    },
    {
        "title": "Vehicle > Car > Bmw",
        "value": 6
    },
    {
        "title": "Car > Bmw > 1 Series",
        "value": 7
    }
]

But I want to see an output like this:

[
    {
        "title": "Vehicle > Car > Bmw > 1 Series",
        "value": 7
    }
]

Where am I making a mistake? Can you provide me with the correct source? Thank you.

2

Answers


  1. Chosen as BEST ANSWER

    I was able to write the code I wanted. It might be useful.

        function categoryTree($parent_id = 0, $spacing = '', $tree_array = array()) {
            $categories = Categories::where('parent_id' ,'=', $parent_id)->orderBy('parent_id')->get();
            foreach ($categories as $item){
                $parent = $item->parent ? $item->parent->name : '';
                $tree_array[] = ['value' => $item->id, 'title' => $spacing . $item->name] ;
                $tree_array = $this->categoryTree($item->id, $spacing .$item->name.' > ', $tree_array);
            }
            return $tree_array;
        }
    

  2. Well if the parent is not 0 you are pulling the name of the grandparent and the name of the parent:

    $category->parent->parent->name.' > '.$category->parent->name.' > '.$category->name
    

    Which is why you only get Car and Bmw when looking at the 1 Series category.

    Instead you could implement a function like this in the model:

    public function breadcrumb() {
        $parents = $this->parent_id !== 0? $this->parent->breadcrumb() . " > " : "";
        return $parents . $this->name;
    }
    

    This will recursively grab the name of all the ancestors.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search