Как получить Eloquent коллекции моделей из модели, которая имеет много различий между двумя? - PullRequest
1 голос
/ 13 мая 2019

У меня есть следующая схема:

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

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

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

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

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

Как видите, вопросы в разделах, а разделы в категориях.

Администратор системы может включить или отключить вопросдля каждого отдельного клиента, поэтому я создаю client_questions, чтобы создать отношение «многие ко многим» между клиентами и вопросами.

Теперь я хотел бы использовать удивительную ценность Eloquent для получения категорий клиентов (чтобы перечислить всевопросы), но я не могу обернуться вокруг конструктора запросов.

В настоящее время я могу задавать вопросы $ client-> через отношение многие ко многим, которые я определил в модели:

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

Ответы [ 2 ]

1 голос
/ 13 мая 2019

К сожалению, вы не сможете определить прямые отношения между clients и categories, однако вы можете использовать существующие отношения, чтобы получить то, что вы хотите.

Для этого я бы предложил использовать смесь с () (ограниченная энергичная загрузка) и гдеHas и начиная с модели 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();

Причина, по которой вы должны использовать оба варианта, заключается в том, что любой из них может привести к тому, что у вас возникнут вопросы, которые не имеют прямого отношения к клиенту.

1 голос
/ 13 мая 2019

Я ответил на это на Laravel цикл по красноречивым моделям с глубокими отношениями

но в основном вы можете использовать точечную нотацию для загрузки далеко идущих моделей в текущую, если они все связаны вниз по цепочке.

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

Это должны быть все категории для поставленного вопроса.

Обратите внимание, что это дорогостоящая операция, поэтому, если коллекция слишком велика, будьте готовы к уловке, но это единственный другой способ, кроме того, что я сталкиваюсь с проповедью над foreach.

...