В моем проекте Laravel у меня есть модель (и базовая таблица) для уроков. Теперь я пытаюсь написать локальную область видимости для возврата всех уроков, которые были завершены конкретным пользователем. Определение «завершено» заключается в том, что в таблице существует строка с именем «lesson_results» с идентификатором этого урока и идентификатором пользователя.

В настоящее время мой прицел выглядит так:

public function scopeFinished($query, User $user)
{
    return $query->join('lesson_results', function($join) use($user)
        {
            $join->on('lesson_results.lesson_id', '=', 'lessons.id')
            ->where("user_id", $user->id);
        });
}

Это вроде работает. Когда я выполняю Lesson :: finished ($ user) -> get (), я получаю правильные уроки для этого пользователя. Однако все уроки из возвращенной коллекции имеют неправильные идентификаторы! Идентификаторы, которые я вижу, - это идентификаторы из таблицы lesson_results. Поэтому, когда я проверяю $ lesson-> id из одного из возвращенных элементов, я получаю не идентификатор из этого урока, а идентификатор из соответствующей строки в таблице lesson_results.

Я проверил mysql, и полный запрос, отправленный из Laravel, выглядит следующим образом

select * from `lessons` inner join `lesson_results` on `lesson_results`.`lesson_id` = `lessons`.`id` and `user_id` = 53

Этот запрос ДОЛЖЕН вернуть два столбца с именем id (один из таблицы уроков и один из таблицы lesson_results), и кажется, что Laravel использует неправильный для возвращаемого результата.

Я не знаю, ошибаюсь ли я в этом или это где-то ошибка?

Это на Laravel 7.6.1.

Edit: Хорошо, я думаю, что действительно решил это сейчас. Не совсем уверен, настоящее ли это решение или просто обходной путь. Я добавил вызов select (), поэтому строка возврата теперь

return $query->select('lessons.*')->join('lesson_results', function($join) use($user)

... что заставляет его возвращать только материал из таблицы уроков. Но действительно ли это нужно?

0
Daniel Malmgren 15 Апр 2020 в 16:08

1 ответ

Лучший ответ

Одно и то же имя столбца будет перекрыто другим.

Решение 1:

Укажите таблицу со столбцом и назовите другой столбец таблицы, если у него такое же имя столбца.

Lesson::finished($user)->select('lessons.*', 'lesson_results.id AS lesson_result_id', 'lesson_results.column1', 'lesson_results.column2',...)->get();

Решение 2:

Или вы можете использовать активную загрузку Eloquent-Builder whereHas (при условии, что вы установили связь между моделью Lesson и моделью LessonResult)

public function scopeFinished($query, User $user)
{
    return $query->whereHas('lessonResults', function($query) use($user)
        {
            $query->where("user_id", $user->id);
        });
}

Итак, вы можете получить такой урок:

Lesson::finished($user)->get();
0
TsaiKoga 15 Апр 2020 в 13:40