如何让父母下的所有孩子都有口才?

问题描述 投票:0回答:10

在我的数据库中,我有一个类别表。类别可以有父类别,使其成为递归关系

我还有一个产品表。每个产品都属于一个类别。

举例来说,我有一棵树,看起来像这样:

Category
    Sub-Category 1
        Sub-Sub-Category 1
            Product 1
            Product 2
            Product 3
            Product 4
        Sub-Sub-Category 2
            Product 5
            Product 6
            Product 7
            Product 8
    Sub-Category 2
        Sub-Sub-Category 3
            Product 9
            Product 10
            Product 11
            Product 12

如果我这样做

$SubCategory1->products
,我希望它给我产品 1-8

如果我这样做

$SubSubCategory3->products
,我希望它给我产品9-12

如果我这样做

$Category->products
,我希望它给我所有产品

基本上,我希望该类别提供属于该类别的所有产品

php laravel eloquent
10个回答
9
投票

在希望找到一个很好地使用 Laravel 的答案之后,我最终放弃了,只是编写代码来完成我想要的事情,结果它比我预期的要小。

public function all_products()
{
    $products = [];
    $categories = [$this];
    while(count($categories) > 0){
        $nextCategories = [];
        foreach ($categories as $category) {
            $products = array_merge($products, $category->products->all());
            $nextCategories = array_merge($nextCategories, $category->children->all());
        }
        $categories = $nextCategories;
    }
    return new Collection($products); //Illuminate\Database\Eloquent\Collection
}

9
投票

这个方法效果很好:

class One extends Model {
    public function children()
    {
        return $this->hasMany(self::class, 'parent_id');
    }

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

8
投票

假设您的模型名称是类别

在类别模型上创建函数

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

在您的控制器上使用上述方法

$categories = Category::with('children')->where('parent_id',0)->get();

5
投票

请尝试下面的 Has Many Through 关系并发布结果

class Category extends Model
{
    public function products()
    {
        return $this->hasManyThrough(
            'App\Product', 'App\Category',
            'parent_id', 'catergory_id', 'id'
        );
    }
}

然后您可以使用

$category->products;
来查找您的产品


2
投票

对于任何正在寻找此答案的人来说,这里有一个简单的解决方案:

class Group extends Model
{
  public function ancestry() 
  {
   return $this->belongsTo('App\Group', 'parent_id')->with('ancestry'); 
  }

  public function descent() 
  {
    return $this->hasMany('App\Group', 'parent_id')->with('descent'); 
  }
}

ancestry函数将为您提供到根的路径,descent将为您提供该节点的所有后代。


1
投票

你最好使用嵌套集合模型。您应该使用此数据结构,因为可以通过简单的方式在 mysql 中获得最快的查询方式。仅使用parent_id属性,您不知道您的树有多深,这会导致您无法知道需要多少个连接。 我为您提供这篇优秀的文章。 管理 mysql 中的分层数据

对于那些使用 Laravel 框架的人,我更愿意推荐这个令人惊叹的包:Baum

https://stacklearn.ir


1
投票

产品类别.php

public function descent()
{
   return $this->hasMany('App\ProductCategory', 'parent_id')->with('descent');
}

控制器

$categories = ProductCategory::with('descent')->get();

想要的树是: A simple category tree

$categories
变量的输出: Output in Array Format


0
投票

假设 $category_id = Category->id 并且您想要一个产品集合作为该类别的子项,我会尝试:

$products = App\Product::with(['SubSubCategory.SubCategory.Category'=>function($query) use ($category_id) {$query->where('id', $category_id);}])- >获取();

能够这样做。您将需要这样的“一对多”反向关系:

//应用程序\子类别

public function Category(){return $this->belongsTo('App\Category');}

//应用\子子类别

public function Sub_Category(){return $this->belongsTo('App\SubCategory');}

//应用\产品

public function SubSubCategory(){return $this->belongsTo('App\SubSubCategory');}

祝你好运。


0
投票

我在表(用户)中创建了 Managed_by,这个解决方案获得了所有无限级别的子级。

在用户模型中

 public function Childs(){
        return $this->hasMany('App\User', 'managed_by', 'id')->with('Childs');
    }

在助手文件中(我的神奇解决方案)

if (!function_exists('user_all_childs_ids')) {
        function user_all_childs_ids(\App\User $user)
        {
            $all_ids = [];
            if ($user->Childs->count() > 0) {
                foreach ($user->Childs as $child) {
                    $all_ids[] = $child->id;
                    $all_ids=array_merge($all_ids,is_array(user_all_childs_ids($child))?user_all_childs_ids($child):[] );
                }
            }
            return $all_ids;
        }
    }

0
投票

Category
模型中

protected static $childrenIds = [];

/**
 * get ids children categories with self id
 * @return array
 */
public function getChildrenIdsAttribute(): array
{
    self::$childrenIds[] = $this->id;
    if ($this->has_children) {
        foreach ($this->children()->active()->get() as $child) {
            $child->children_ids;
        }
    }

    return self::$childrenIds;
}

public function getHasChildrenAttribute()
{
    return (bool)$this->children->count();
}

public function scopeActive($query)
{
    return $query->where('is_active', '=', true);
}

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

路线

Route::get('category/{category}/products', [ProductController::class, 'categoryProducts'])

控制器

public function categoryProducts(Category $category): JsonResponse
{
    $product = Product::whereIn('category_id', $category->children_ids)->get();

    return response()->json($product);
}
© www.soinside.com 2019 - 2024. All rights reserved.