Laravel Eloquent 获取相关表中的最新一行。

12 浏览
0 Comments

Laravel Eloquent 获取相关表中的最新一行。

我有两个表,bookschapters。一本书有很多章节。

Book模型:

public function chapters() {
   return $this->hasMany(Chapter::class);
}

Chapter模型:

public function book() {
   return $this->belongsTo(Book::class);
}

我想要通过单个查询获取书籍列表以及它们各自的最新章节,就像这样:

$books = Book::with(['authors', 'categories', 'chapters' => function($q) {
   $q->orderBy('updated_at', 'desc')->first();
}]->get();

但是它不起作用。章节返回一个空数组。如果我在子查询中移除first(),它就可以正常工作。

有没有办法只用一个查询来实现这个功能。我不想获取所有相关的章节然后再保留一个,也不想使用多个查询。唯一让我感觉好一点的方法是使用join,这样对吗?

非常感谢您的帮助!

0
0 Comments

Laravel eloquent获取关联表的最新行的问题出现的原因是,在Laravel 8.4版本中没有提供->latestOfMany方法。为了解决这个问题,可以通过给hasOne关联添加自连接来过滤每个主模型的最新关联模型。

具体的解决方法是,在主模型的lastchapter方法中,通过自连接的方式来筛选出每个主模型关联的最新章节模型。代码如下所示:

public function lastchapter()
{
    return $this->hasOne(Chapter::class)->join(DB::raw("(
           SELECT MAX(id) as id, book_id
           FROM `books` as `books_sub`
           GROUP BY book_id
        ) as lastchapters"), function ($join) {
        $join->on("lastchapters.id", '=', "books.id");
    })->whereRaw('lastchapters.id = books.id');
}

上述代码中,通过使用join方法和DB::raw函数,创建了一个自连接的子查询,该子查询会找出每个书籍(主模型)对应的最大id(最新章节id),并将其作为临时表lastchapters。然后,通过on方法将lastchapters的id与书籍表的id进行连接,最后通过whereRaw方法来筛选出与lastchapters的id相等的记录,即每个书籍关联的最新章节模型。

通过以上方法,就可以解决使用hasOne关联获取关联表的最新行的问题。

0
0 Comments

Laravel Eloquent 获取相关表的最新行

在Laravel 8中,引入了一些新的辅助函数:latestOfMany、oldestOfMany和ofMany。这些函数可以帮助我们获取相关表中的最新行、最旧行或所有行。

对于我们的示例,我们可以使用latestOfMany函数来获取最新的章节。具体代码如下:

public function latestChapter() {
    return $this->hasOne(Chapter::class)->latestOfMany();
}

这个函数将返回与当前模型关联的Chapter模型中的最新行。

这个问题的出现原因是,我们希望能够方便地获取相关表中的最新行。在以前的版本中,我们可能需要手动编写查询语句来实现这个功能。但是在Laravel 8中,引入了这些新的辅助函数,使得我们能够更加简洁和高效地实现这个功能。

通过使用latestOfMany函数,我们可以避免手动编写复杂的查询语句,而是直接调用函数来获取我们需要的数据。这不仅简化了代码的编写,还提高了代码的可读性和可维护性。

总结起来,Laravel 8中的latestOfMany函数为我们提供了一种简洁、高效的方式来获取相关表中的最新行。通过使用这个函数,我们可以避免手动编写复杂的查询语句,提高代码的可读性和可维护性。

0
0 Comments

Laravel eloquent get the latest row of related table问题的出现原因是关系查询是分开的查询,无法对预加载关系添加限制。如果这样做,将限制整个关系查询,而不是每个相关对象的限制。解决方法取决于Laravel的版本。

对于Laravel >= 8.42.0版本,解决方法是使用latestOfMany()方法。需要为最新章节定义一个新的关系,并使用这个新的关系方法来获取所需的记录。

对于早期版本的Laravel,解决方法类似,但效率不高。需要定义一个新的关系,使用latest()方法返回最新的记录。

现在,不再预加载整个chapters关系,而是仅预加载最新的latestChapter关系。

最后,某些情况下了使用latest_chapter()方法和take(1)方法,但并不起作用。正确的方法是使用hasOne关系和take(1)方法。此外,可以根据需要在关系中添加条件。

某些情况下使用latest()方法会产生不一致的结果,但这是该问题的正确解决方法。如果有其他问题,请展示你的实现和认为不正确的地方。

0