Laravel "извлеченный" наблюдатель удаляет мои отношения между объектами

У меня такой код:

$comments = Comment::with('user.country')
        ->limit(200)
        ->get(['id', 'comment', 'user_id'])

Я добавил полученного наблюдателя, чтобы добавить кое-что к исходному комментарию. Что-то вроде этого:

public function retrieved(Comment $comment)
{
    $comment_country = $comment->user->country->name;
}

И проблема в том, что даже если я уже загрузил пользователя и страну с помощью with('user.country'), комментарий не содержит объектов пользователя или страны и попадает в базу данных для каждого из 200 моих комментариев.

Я протестировал этот код без наблюдателя и действительно получил объекты пользователя и страны. Есть идеи, как заставить наблюдателя использовать уже загруженного пользователя и страну, потому что сейчас он просто создает целый объект nu?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
434
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Здесь выполняется более одного запроса. Вам необходимо знать порядок, в котором происходит активная загрузка.

Запрашивается базовый набор записей для Comment, и набор результатов заполняется в модели посредством гидратации (вызывая запуск retrieved). Затем выполняется активная загрузка путем сбора всех необходимых ключей из этих моделей, а затем выполнения запроса для получения дочерних элементов. Когда этот результат возвращается, детей снова сравнивают со своими родителями.

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

Событие retrieved запускается, как только модель гидратируется из построителя запросов.

Есть предложения, как получить желаемый эффект? Я хочу, чтобы название страны было внутри моего комментария, но я не хочу делать 200 запросов, чтобы получить это, я знаю, что могу выполнить соединение или я могу выполнить итерацию по объектам и добавить его, но решение для наблюдателя выглядело более элегантным.

Mihai Vinaga 03.08.2018 01:08

он не будет использовать событие retrieved, это точно ... в исходном вопросе вам следует подробнее рассказать о том, что вы на самом деле пытаетесь сделать и почему это необходимо сделать в данный момент.

lagbox 03.08.2018 01:12

Вы были совершенно правы, что не сделали этого изнутри. Мое решение было следующим. Я удалил код наблюдателя, который получил название страны, и сделал следующее:

protected $visible = ['id', 'name'];
protected $appends = ['country'];

а также

public function getCountryAttribute()
{
    return $this->user->country->name;
}

что вместе с отлично работало

$comments = Comment::with('user.country')
    ->limit(200)
    ->get(['id', 'comment', 'user_id'])

Обратите внимание, что в этом моем решении основное внимание уделяется тому факту, что впоследствии я отображаю эту информацию как json.

Другие вопросы по теме