You probably need to write a recursive method.
Get all subcategories' id as array
I know there's a ton of posts on subcategories subject here but I've checked most of them and none seem to answer my question.
I have "categories" table with records are either a root category or related to a root category by parent_id like this;
ID | NAME | PARENT_ID
------------------------------------
1 | root | null
2 | child 1 | 1
3 | child 1.1 | 2
4 | child 1.1.1 | 3
What I want to achieve;
subCategoriesArray(1); // [2, 3, 4]
Reason : I'm making a category edit page and I want users to be able to change a category's parent. In order to prevent a category from being a child of its own child, I need to eliminate its subcategories in the category selection box.
My code so far :
function subCategoriesArray($id){
$data=[];
$children = Category::whereParentId($id)->get();
foreach ($children as $child){
$data[] = $child->id;
$data = array_merge($data, subCategoriesList($child->id));
}
return $data;
}
it only returns category's direct children for some reason.
Category Model :
class Category extends Model
{
use HasFactory;
use SoftDeletes;
public function children(){
return $this->hasMany(Category::class, 'parent_id')->with('children');
}
public function parent(){
return $this->hasOne(Category::class, 'id', 'parent_id');
}
}
Honestly, I’m not sure why your function doesn’t work. It seems to me like it ought to.
Playing around with a test table and a slightly differently laid-out function, the version pasted below seems to work for me, even though it does pretty much exactly the same thing as yours. The only fundamental differences are that I made it a method on the model rather than a standalone helper function, and that I used a collection instead of a plain array for easier sorting (it works with a plain array as well, using array_merge like you did).
// Model
class Category extends Model {
use HasFactory;
use SoftDeletes;
public function children() {
return $this->hasMany(self::class, 'parent_id');
}
public function parent() {
return $this->hasOne(self::class, 'id', 'parent_id');
}
public function getNestedChildren() {
$data = \collect();
$children = self::whereParentId($this->id)->get();
foreach ($children as $child) {
$data->push($child->id);
$data = $data->merge($child->getNestedChildren());
}
return $data;
}
}
// Controller
$category = Category::find(1);
$nestedChildren = $category->getNestedChildren();
Please or to participate in this conversation.
