【问题标题】:How do I get all children that fall under a parent in eloquent?我如何让所有属于父母的孩子都口才?
【发布时间】:2016-07-05 04:35:22
【问题描述】:

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

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

比如说,我有一棵看起来像这样的树:

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,我希望它给我所有产品

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

【问题讨论】:

  • 你检查过Has Many Through吗?
  • 本例中只有 2 个表,Has Many Through 对我有何帮助?
  • Store 也是一个类别吗?
  • 是的,抱歉,应该澄清一下

标签: laravel eloquent


【解决方案1】:

在希望找到一个很好地使用 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
}

【讨论】:

    【解决方案2】:

    假设您的模型名称是类别

    在类别模型上创建一个函数

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

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

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

    【讨论】:

    • 这会给出具有特定父 ID 的类别。我想要直接或间接具有匹配父级的产品
    【解决方案3】:

    这种方法效果很好:

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

    【讨论】:

    • 这对我来说仍然只返回一个级别。你怎么称呼它?
    【解决方案4】:

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

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

    然后您可以使用$category->products; 查找您的产品

    【讨论】:

    • 它可以升级 1 级,但不能用于其他任何东西。 example。在那个屏幕截图中,“托盘”有 4 个产品,它的父级有 12 个产品,而且它的父级的父级应该有更多。
    • 尝试记录生成的查询以了解如何解释关系船舶信息..
    【解决方案5】:

    您最好使用嵌套集模型。您应该使用这种数据结构,因为可以通过一种简单的方式在 mysql 中获得最快的查询方式。只有一个 parent_id 属性,您不知道您的树有多深,这会导致您无法知道需要多少连接。 我为您提供这篇出色的文章。 managing-hierarchical-data-in-mysql

    对于那些使用 laravel 框架的人,我更喜欢推荐这个神奇的包:Baum

    https://stacklearn.ir

    【讨论】:

    • 这件事为我节省了很多时间。强烈推荐它。
    【解决方案6】:

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

    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 将为您提供该路径的所有后代节点。

    【讨论】:

      【解决方案7】:

      我在表(用户)中创建了 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;
              }
          }
      

      【讨论】:

        【解决方案8】:

        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);
        }
        

        【讨论】:

          【解决方案9】:

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

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

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

          //应用\子类别

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

          //App\SubSubCategory

          公共函数 Sub_Category(){return $this->belongsTo('App\SubCategory');}

          //应用\产品

          公共函数SubSubCategory(){return $this->belongsTo('App\SubSubCategory');}

          祝你好运。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-03-26
            • 1970-01-01
            • 2021-12-17
            • 1970-01-01
            • 1970-01-01
            • 2018-03-18
            • 1970-01-01
            相关资源
            最近更新 更多