首页 > 解决方案 > 从本地 Eloquent 范围返回错误的 ID

问题描述

在我的 Laravel 项目中,我有一个课程模型(和一个基础表)。现在我正在尝试编写一个本地范围来返回特定用户已完成的所有课程。“完成”的定义是在名为“lesson_results”的表中存在一行,其中包含本课的 ID 和用户 ID。

我的范围目前看起来像这样:

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() 时,我会为该用户获取正确的课程。但是返回的集合中的课程都有错误的ID!我看到的 ID 是来自课程结果表的 ID。因此,当我从其中一个返回的项目中检查 $lesson->id 时,我没有从该课程中获得 ID,而是从 course_results 表中的相应行中获得 ID。

我已经检查了 mysql,从 Laravel 发送的完整查询如下

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

该查询返回名为 id 的两列(一列来自课程表和一列来自课程结果表),并且 Laravel 似乎在返回结果中使用了错误的列。

我不知道我是否以错误的方式进行此操作,或者它是否是某个地方的错误?

这是在 Laravel 7.6.1 上。

编辑:好的,我想我现在真的解决了。不确定它是真正的解决方案还是只是一种解决方法。我添加了一个 select() 调用,所以现在的返回行是

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

...这使得它只返回课程表中的东西。但这真的需要吗?

标签: laraveleloquentlaravel-7

解决方案


相同的列名之一将被另一个覆盖。

解决方案1:

指定具有该列的表,如果其他表的列具有相同的列名,则为该列指定别名。

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

解决方案2:

或者你可以使用 Eloquent-Builder eager-loading ,(假设你已经建立了模型和模型whereHas之间的关系)LessonLessonResult

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

所以你可以得到这样的教训:

Lesson::finished($user)->get();

推荐阅读