Laravel: как получить эту вложенную модель - PullRequest
0 голосов
/ 11 января 2019

В Laravel у меня есть ModelA, ModelB и ModelC. ModelA имеет много ModelB. ModelB имеет много ModelC. Я хочу получить все ModelC для выбора ModelA. Как мне это сделать?

Я попробовал следующее:

$models = ModelC::with(['modelB','modelB.modelA' => function ($query) {
    $query->where('owner', 123);
}])->get();

Но первый запрос в этом случае - select * from model_c. Очевидно, не результат, который я ищу.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Мне удалось решить эту проблему с помощью вложенных вызовов whereHas следующим образом:

$models = modelC::whereHas('modelB', function ($query) {
    $query->whereHas('modelA', function ($query) {
        $query->where('owner', 123);
    });
})->get();

Laravel на помощь, еще раз!

0 голосов
/ 11 января 2019

Представьте, что вы получили 100 объектов из базы данных, и каждая запись имела 1 связанную модель (то есть, принадлежит). Использование ORM приведет к 101 запросу по умолчанию; один запрос для исходных 100 записей и дополнительный запрос для каждой записи, если вы получили доступ к связанным данным на объекте модели. Предположим, что в псевдокоде вы хотите перечислить всех опубликованных авторов, которые опубликовали сообщение. Из коллекции постов (каждый пост имеет одного автора) вы можете получить список имен авторов, например:

$posts = Post::published()->get(); // one query

$authors = array_map(function($post) {
    // Produces a query on the author model
    return $post->author->name;
}, $posts);

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

Стремительная загрузка

Как я уже говорил, ORM «ленивые» ассоциации нагрузки. Если вы намереваетесь использовать связанные данные модели, вы можете урезать этот 101 запрос до 2 запросов с помощью активной загрузки. Вам просто нужно сообщить модели, что вам нужно, чтобы загрузить ее с нетерпением.

Вот пример из руководства по активной записи Rails об использовании активной загрузки. Как видите, эта концепция очень похожа на концепцию активной загрузки Laravel.

$posts = Post::with('author')->limit(100)->get();

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...