Как мне создать вложенный список категорий в Laravel?
Я хочу создать что-то вроде следующего примера:
Поля моей таблицы:
ID | Name | Parent_id
Если мне нужно добавить еще один столбец в мою таблицу, как глубина, пожалуйста, сообщите мне.
Я использую следующий код, но думаю, что это не лучшее решение для создания вложенного списка категорий, кроме того, я не могу передать эту функцию на мой взгляд:
function rec($id)
{
$models = Category::find($id);
foreach ($models->children as $chield) {
rec($chield->id);
}
return $models->all();
}
function main () {
$models = Category::whereNull('parent_id')->get();
foreach ($models as $parent) {
return rec($parent->id);
}
Вы можете сделать самореферентную модель:
class Category extends Model {
public function parent()
{
return $this->belongsTo('Category', 'parent_id');
}
public function children()
{
return $this->hasMany('Category', 'parent_id');
}
}
и сделать рекурсивное отношение:
// recursive, loads all descendants
public function childrenRecursive()
{
return $this->children()->with('childrenRecursive');
}
и заводить родителей со всеми своими детьми
$categories = Category::with('childrenRecursive')->whereNull('parent')->get();
Наконец, вам нужно просто перебрать детей, пока они не станут нулевыми. С этим могут быть некоторые проблемы с производительностью, если вы не будете осторожны. Если это довольно маленький набор данных, который вы планируете оставить таким, это не должно быть проблемой. Если это будет постоянно растущий список, возможно, имеет смысл иметь root_parent_id
или что-то, чтобы запросить и собрать дерево вручную.
Если кому-то нужен лучший ответ, посмотрите мой ответ, он помог мне, когда я столкнулся с такой проблемой.
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;
}
}
И в вашем контроллере просто проверьте это:
$category = Category::find(1);
$category_ids = $category->getDescendants($category);
Это приведет к идентификаторам в массиве всех потомков вашей категории, где id = 1.
затем :
$products = Product::whereIn('category_id',$category_ids)->get();
Добро пожаловать =)
Я решил проблему:
$traverse = function ($categories) use (&$traverse) {
foreach ($categories as $category) {
$traverse($cat->Children);
}
};
$traverse(array ($category));
Единственная проблема заключается в том, что я не могу рассчитать информацию в моем контроллере
public function Children()
{
return $this->hasMany($this, 'parent');
}
public function Parent()
{
return $this->hasOne($this,'id','parent');
}
Ища что-то в этой области, я хотел бы поделиться функциональностью для получения уровня глубины ребенка:
function getDepth($category, $level = 0) {
if ($category->parent_id>0) {
if ($category->parent) {
$level++;
return $this->getDepth($category->parent, $level);
}
}
return $level;
}
Может быть, это кому-то поможет!
Ура!