Laravel 11.x 通过关系获取关系的雄辩方式(共 4 个表)

问题描述 投票:0回答:1

我正在使用最新版本的 Laravel。我正在尝试设置一个通过其他中间表的模型方法关系。

了解下面的表结构,我的目标是检索(仅)注册属于课程模型的课程的学生集合。

课程->课程->学生 课程->学生

我已经很接近了,正如您在课程模型、student() 方法中看到的那样,我可以检索所有课程及其学生的集合......但我不希望课程随之而来。

有没有一种雄辩的方法来完成这个?

谢谢!

表结构

课程
编号
..

课程
编号
课程_id
..

学生课程
编号
课程_id
学生id
..

同学们
编号
..

型号

课程

    /**
     * @return HasMany
     */
    public function course(): HasMany
    {
        return $this->hasMany(Course::class);
    }

    /**
     * @return HasManyThrough
     */
    public function class(): HasManyThrough
    {
        return $this->hasManyThrough(ClassModel::class, Course::class);
    }

    /**
     * @return HasManyThrough
     */
    public function student()
    {
        // this works as expected, but brings courses too, I only want students.
        return $this->hasManyThrough(StudentCourse::class, Course::class)->with('student');
    }

课程

    /**
     * @return HasMany
     */
    public function class(): HasMany
    {
        return $this->hasMany(ClassModel::class);
    }

    /**
     * @return BelongsTo
     */
    public function curriculum(): BelongsTo
    {
        return $this->belongsTo(Curriculum::class, 'curriculum_id', 'id');
    }

    /**
     * @return HasManyThrough
     */
    public function student(): HasManyThrough
    {
        return $this->hasManyThrough(Student::class, StudentCourse::class,
            'course_id',
            'id',
            'id',
            'student_id'
        );
    }

学生课程


    /**
     * @return BelongsTo
     */
    public function student(): BelongsTo
    {
        return $this->BelongsTo(Student::class);
    }

    /**
     * @return BelongsTo
     */
    public function course(): BelongsTo
    {
        return $this->BelongsTo(Course::class);
    }

学生


    /**
     * @return HasOne
     */
    public function user(): HasOne
    {
        return $this->HasOne(User::class, 'userID', 'user_id');
    }

    /**
     * @return HasManyThrough
     */
    public function course(): HasManyThrough
    {
        return $this->HasManyThrough(Course::class, StudentCourse::class,
            'student_id',
            'id',
            'id',
            'course_id'
        );
    }

    /**
     * @return HasManyThrough
     */
    public function class(): HasManyThrough
    {
        return $this->HasManyThrough(ClassModel::class , StudentClass::class,
        'student_id',
        'id',
        'id',
        'class_id'
        );
    }
php laravel eloquent
1个回答
0
投票

我不认为你会找到一个完全基于 Eloquent 的解决方案来解决你的问题。根据我的经验,Eloquent 可以很好地处理一对多(两个表)和多对多(三个表)关系,但除此之外它就会变得混乱。

由于您不需要任何课程信息,因此最好使用构建器查询,例如:

class Curriculum extends Model
{
    ...

    public function students()
    {
        return Student::select('students.*')
            ->join('students_courses', 'students.id', '=', 'students_courses.student_id')
            ->join('courses', 'students_courses.course_id', '=', 'courses.id')
            ->where('courses.curriculum_id', $this->id)
            ->distinct()
            ->get();
    }
}

您需要

select('students.*')
来防止任何其他表列被拖入学生模型中,但至少您最终得到的只是学生的集合。

我建议将这样的函数放在课程模型的单独的自定义构建器类中,这样可以使模型类保持干净。看看使用

newEloquentBuilder
,有很多文章描述了如何实现它们。

© www.soinside.com 2019 - 2024. All rights reserved.