如果产品仅与一个 "subcategory" 相关,如何获取 "main category" 的产品?

How to get products of a "main category" if a product is related to only one "subcategory"?

如果一个产品只与一个“子类别”相关,我如何获得一个“主要类别”的所有产品?产品仅与子类别相关,而子类别始终是主类别的一部分。所以我想把所有产品都放在主要类别中。像下面这样的查询将不起作用或 return 没有产品,因为没有产品与类别 #1 相关。

Categories::where(['id' => 1])->products();

Models/Category.php

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

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

Models/Product.php

public function category(): BelongsTo
{
    return $this->belongsTo(Category::class);
}

我需要什么来do/change获取主要类别的所有产品(最好不检查 ID #1 的类别是否是主要类别)?

您可以使用 hasManyThrough 关系。你从这个link

检查

将此代码添加到您的 Category 模型中:

public function products(){
    return $this->hasManyThrough(
        Product::class,
        Category::class,  
        "parent_id", 
        "category_id", 
        "id", 
        "id"
    );
}

也许,我对你的外键和主键有误。请检查。

查询分层数据结构这个问题的一个常见解决方案是闭包 Table。网上有很多关于此模式的讨论,所以我不会尝试完全重述,但简短的总结是您存储每个对象与其所有祖先之间的每条路径以及它们之间的深度。这为您提供了一个包含列(ancestor_id、descendant_id、深度)的 table,因此您可以通过该 table 加入以收集链接到任何给定后代祖先的所有对象, 或任何祖先的后代。

这里是一个示例查询,说明它在实践中如何查询给定祖先类别的所有后代,可能存在一些语法问题,因为我没有真正的数据库来 运行 这个反对。

SELECT products.* FROM products
  INNER JOIN category_closure ON products.category_id = category_closure.descendant_id
WHERE category_closure.ancestor_id = 1;

我们目前将此解决方案用于几乎完全相同的问题,产品分配到类别层次结构中的任何位置。然而,我们是在一个 Doctrine 项目中这样做的,所以我们的解决方案的实现细节可能对这里没有帮助。

在 Laravel 中有现有的库可以使这更容易,例如 https://github.com/franzose/ClosureTable(我不能保证质量,只是现在在搜索中找到的)。