【问题标题】:How to execute Laravel nested query如何执行 Laravel 嵌套查询
【发布时间】:2022-01-15 19:47:49
【问题描述】:

我有以下 3 张桌子

教室

id subject

注册学生

id user_id class_id

帖子

id class_id type attachment

模型

Classroom.php

public function posts()
{
   return $this->hasMany(Post::class);
}

RegisteredStudents.php

public function classroom()
{
  return $this->belongsTo(Classroom::class);
}

Post.php

public function classroom()
{
  return $this->belongsTo(Classroom::class);
}

现在我需要获取某个学生注册的特定班级的所有帖子。

例如,一个学生在教室表中注册了 id 号为 1 的班级。因此会在registered_students 表上注明该特定用户是在该特定类下注册的。每个班级可能在帖子表中有多个帖子。并且用户需要获得他班级的所有帖子。

我正在尝试这样的事情:

 $registered_classes = RegisteredStudent::where('user_id',$user->id)
            ->where(function ($q) use ($class_id){
                Post::where('class_id',$class_id);
            })->get();

这绝对是不正确的。什么是正确的查询。

【问题讨论】:

    标签: php laravel laravel-7


    【解决方案1】:

    您首先需要纠正TheArKa 在他的回答中所说的关系(因为表和类名没有正确遵循 laravel eloquent 约定)。

    Classroom.php

    public function posts()
    {
        return $this->hasMany(Post::class, 'class_id');
    }
    

    RegisteredStudent.php

    public function classroom()
    {
        return $this->belongsTo(Classroom::class, 'class_id');
    }
    

    那么正确的查询应该是:

    $posts_of_class_of_user =
    RegisteredStudent::where('user_id',$user->id)->first()->classroom->posts;
    

    这将首先从RegisteredStudent获取注册用户,然后从belongsTo关系获取Classroom实例,然后从hasMany关系获取所有相关的posts

    请注意,使用关系,您可以避免复杂的查询,特别是在您的情况下。您不需要任何复杂的查询。只需使用雄辩的关系方法即可。

    【讨论】:

    • 它抛出“Eloquent builder 实例上不存在属性 [classroom]。”
    • 哎呀,只是在课堂前缺少->first()。现在更新我的答案
    • RegisteredStudent 与 Post 没有直接关系。所以->posts 应该抛出一个错误。如果您在模型中建立“hasManyThrough”关系,这可能会起作用。 @Psycho
    • 您所说的是直接访问帖子而不使用课堂 RegisteredStudent::where('user_id',$user->id)->first()->posts,这是由 hasManyThrough 完成的,但我正在访问 classroom->posts
    【解决方案2】:

    您已创建 RegisteredStudent 模型,具有 classroom 关系。问题是,如果您的 foreign_key 与 Laravel 行为不同,您必须将其包含在关系中。像这样:

    Classroom.php

    public function posts(): HasMany
    {
        return $this->hasMany(Post::class, 'class_id');
    }
    

    *Laravel Behavior 需要你使用classroom_id 而不是class_id

    RegisteredStudent.php

    public function classroom(): BelongsTo
    {
        return $this->belongsTo(Classroom::class, 'class_id');
    }
    
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
    

    Post.php

    public function classroom(): BelongsTo
    {
        return $this->belongsTo(Classroom::class, 'class_id');
    }
    

    更详细地了解 Laravel 行为的完整示例here

    *已编辑

    然后,如果您想获取学生注册的特定班级的所有帖子,您可以使用with 方法:

    public function getAllPostsClassroom()
    {
        $registeredUser = RegisteredStudent::where('user_id', $user->id)->with(['classroom.posts' => function($query) use ($class_id) {
            $query->where('class_id', $class_id);
        }])->first();
    }
    

    您将在注册用户的Classroom 中获得所有Posts

    【讨论】:

    • 这并没有完全回答这个问题。他主要是要求正确的查询
    • 要查询什么?
    • @OsmanRafi 已编辑。请让我知道它是否有效。
    • 此查询不返回 Posts,而是返回 RegiateredStudent 实例
    • 他们应该有一个从UserClassroomhasManyThrough 关系。 RegisteredStudent 只是一个枢轴模型,不应真正直接参与查询。
    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 2020-01-23
    • 1970-01-01
    • 2017-05-12
    • 2013-03-24
    • 2021-12-25
    • 1970-01-01
    相关资源
    最近更新 更多