【发布时间】:2019-12-03 09:42:07
【问题描述】:
这是我过去几个小时试图解决的一个挑战。
我有一个Page 模型和一个Category 模型。
一个页面可以属于多个类别,每个类别可以有多个页面,因此它们之间具有多对多的关系。
最重要的是,每个类别都有一个父类别,因此每个类别之间是一对多的。
因此,考虑到所有这些,以下是模型:
页面模型
// table ['id', 'title', 'content', 'created_at', ...]
class Page extends Model
{
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
类别模型
// table ['id', 'category_id', 'name', 'created_at', ...]
class Category extends Model
{
public function pages()
{
return $this->belongsToMany(Page::class)
}
public function categories()
{
return $this->hasMany(Category::class);
}
public function parent()
{
return $this->belongsTo(Category::class, 'category_id');
}
}
我确实有一个category_page 表与category_id 和page_id 来链接这种关系。
现在是棘手的部分。
我正在尝试创建一个 Eloquent 查询,给定 category_id 我将能够获取此类别下的所有页面以及此类别的子类别下的所有页面。
我可能可以通过嵌套 SQL 查询中的多个连接或简单的 foreach 循环来递归地获取子页面来实现这一点(但这会花费大量不必要的时间)。
有什么好的优雅的方法吗?
提前致谢。
编辑:
在 Laravel 中有一种方法可以建立递归关系,并在一行代码中包含所有带有页面的子类别。
//在类别模型中
public function childrenCategories()
{
return $this->hasMany(Category::class)->with('childrenCategories');
}
现在我可以了
Category::whereId($rootCategoryId)->with('childrenCategories')->first();
这样我就有了一个所有类别的嵌套树,然后我可以加载它的页面关系,我就完成了。
但是,它存在一个巨大的问题,它执行的查询量非常大(每个嵌套级别的查询),并且在生产应用程序中使用它没有意义。 所以我确实有一个解决方案,这很糟糕,所以我愿意接受其他建议。
【问题讨论】: