如何从两者之间有很多分离度的模型中获取 Eloquent 个模型集合?

How to get an Eloquent collections of models from a model that has many degress of separation between the two?

我有以下架构:

+------------+
| categories |
+------------+
| id         |
+------------+

+-------------+
| sections    |
+-------------+
| id          |
| category_id |
+-------------+

+------------+
| questions  |
+------------+
| id         |
| section_id |
+------------+

+------------+
| clients    |
+------------+
| id         |
+------------+

+-------------------+
| client_questions  |
+-------------------+
| client_id         |
| question_id       |
+-------------------+

如您所见,问题是分节的,节是分类别的。

系统管理员可以为每个单独的客户打开或关闭问题,因此我创建 client_questions 来创建客户和问题之间的多对多关系。

现在,我想利用 Eloquent 的强大功能来获取客户的类别(列出所有问题),但我似乎无法全神贯注于查询生成器。

基本上,我目前可以通过我在模型中定义的多对多关系来执行 $client->questions:

public function questions() {
    return $this->belongsToMany(Question::class,'client_questions','client_id','question_id');
}

但考虑到分离程度,我似乎无法弄清楚如何在客户和类别之间做同样的事情。

基本上我想$client->categories这样我就可以列出整个采访:

@foreach( $client->categories as $category)
  @foreach( $category->sections as $section)
    @foreach( $secion->questions as $question )
      {{ $question->question }}
    @endforeach
  @endforeach
@endforeach

我已经在

上回答了这个问题

但基本上您可以使用点表示法将影响深远的模型加载到当前模型上,只要它们在链下都是相关的。

$questions->load(['sections.categories' => function($q) use(&$categories){
    $categories = $q->get();
}]);

这应该是所提供问题的所有类别。

请注意,这是一项昂贵的操作,因此如果集合太大,请做好准备,但这是我遇到的除了 foreaching over foreaches 之外的唯一其他方法。

遗憾的是,您将无法定义 clientscategories 之间的直接关系,但是,您可以使用现有关系来获得所需内容。

为此,我建议混合使用 with() (constrained eager loading) and whereHas 并从 Category 模型开始:

$categories = Category::with([
    'sections.questions.clients' => function ($query) use ($clientId) {
        $query->where('id', $clientId);
    },
])->whereHas('sections.questions.clients', function ($query) use ($clientId) {
    $query->where('id', $clientId);
})->get();

您必须同时使用两者的原因是因为单独使用任何一个都可能导致您遇到与客户没有直接关系的问题。