laravel 嵌套急切加载获取和第一个函数

Posted

技术标签:

【中文标题】laravel 嵌套急切加载获取和第一个函数【英文标题】:laravel nested eager loading take and first function 【发布时间】:2020-11-09 18:34:41 【问题描述】:

我有 3 个模型

VideoTopicVideoVideoProgress

关系如下:

VideoTopic:

/**
     * topic to videos Relation
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function videos() : \Illuminate\Database\Eloquent\Relations\HasMany 
        return $this->hasMany("App\Video", "topic_id");
    

Video:

/**
     * video to topic relation
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function topic() : \Illuminate\Database\Eloquent\Relations\BelongsTo 
        return $this->belongsTo("App\VideoTopic", "topic_i");
    

    public function progresses() 
        return $this->hasMany("App\VideoProgress", "video_id");
    

VideoProgress:

public function user() 
        return $this->belongsTo("App\User", "user_id");
    

    public function video() 
        return $this->belongsTo("App\Video", "video_id");
    

我正在尝试获取所有视频主题及其视频和每个视频的进度,但我只想获取保存在数据库中的最后一个进度,因此我的代码如下:

$topics = VideoTopic::first()->with(["videos" => function ($query) 
            $query->orderBy("order");
            $query->with(["progresses" => function ($query) 
                $query->latest();
                $query->take(1);
            ]);
        ])->orderBy("order")->get();

但在上面的代码中,不是为每个视频提供一个进度,而是只提供为其中一个视频保存的最后一个进度(而不是其他视频的进度)。 它只给出最后一个。

但我想要的是为每个视频获得一个进度(如果可用)。

我也试过下面的代码:

$topics = VideoTopic::first()->with(["videos" => function ($query) 
            $query->orderBy("order");
        , "videos.progresses" => function ($query) 
                $query->latest();
                $query->take(1);
            ])->orderBy("order")->get();

当我先使用而不是使用时,它也不起作用。

【问题讨论】:

尝试删除take(1),因为这里只有你想要的。 如果你使用orderBy('created_at', 'desc')而不是latest会怎样 @FelippeDuarte latest 只是按 created_at 排序结果。我只想取得一个进步 @Matt 试过但没有任何改变。我认为最新的本身就是这样做的 【参考方案1】:

使用 hasOne 建立新关系:

  public function lastProgresses() 
        return $this->hasOne("App\VideoProgress", "video_id")->latest();
    

现在用这个关系代替旧的:

$topics = VideoTopic::with(["videos" => function ($query) 
            $query->orderBy("order");
        , "videos.lastProgresses"])->orderBy("order")->first();

【讨论】:

以上是关于laravel 嵌套急切加载获取和第一个函数的主要内容,如果未能解决你的问题,请参考以下文章

带有约束的 Laravel 嵌套急切加载

Laravel Eloquent ORM - 获取第一和第三表数据

带有嵌套关系的 Laravel 急切加载

laravel eloquent - 在嵌套急切加载的关系上不使用

在 laravel 中分页急切加载

如何在 laravel 中检索用户时急切加载?