获取对象及其与 Eloquent ORM 的所有关系

Get Object and all its relations with Eloquent ORM

我有两个数据库table。一个用于保存基本数据,一个用于保存数据的历史记录。例如:我有一个 table books 和一个 table book_data

现在,在书中 table 我有一个像 sales 这样的专栏。这是今天这本书的销量。在 book_data 中,我还保存了 sales 数字,但另外添加了此计数的日期。例如,我可以看到这本书在过去 7 天内的销量。

要通过 ID 获取图书,我正在执行以下操作

try {
    $book = Book::findOrFail($id);
    return [
        'status'    => 'success',
        'data'      => $post
    ];
} catch (ModelNotFoundException $e) {
    return response()->json([
        'status'    => 'error',
        'data'      => 'No book with this id found'
    ], 400);
 }

但是现在,我也想得到销售额的"history"。意思是,当我 select 一本书时,我还想从我的 book_data table 中获取所有相关值。所以,当我保存了过去 4 天的数据后,我还想在我的回复中显示这些数据。

在我的 Book 模型中 class 我有

public function history()
{
    return $this->hasMany('App\Models\BookData');
}

这段代码我已经写好了,基本可以了...

public function show($id)
{
    try {
        $post = Book::with('history')->get()->find($id);
        return [
            'status'    => 'success',
            'data'      => $post
        ];
    } catch (ModelNotFoundException $e) {
        return response()->json([
            'status'    => 'error',
            'data'      => 'No post with this id found'
        ], 400);
    }
}

...但是,此解决方案存在多个问题。

1st:这对性能来说不是很糟糕吗,因为我首先获取所有对象及其关系,然后 然后 我按 id 过滤它? 第二:当我传递一个不存在的 ID 时,不会抛出 ModelNotFoundException

那么,我将如何实现这一点,最好的方法是什么?兼顾性能和可读性以及最佳案例。

首先,不需要get()。您可以单独使用 find()

$post = Book::with('history')->find($id);

不会查询所有记录并在之后进行过滤。它基本上只是为 id 添加一个 WHERE 子句,return 是第一个(也是唯一的)结果。


仅当您使用 findOrFail() 时才会抛出 ModelNotFoundExceptionfind() 将只是 return null。这就是你想要的:

$post = Book::with('history')->findOrFail($id);