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

时间:2015-07-09 10:53:52

标签: php laravel eloquent lumen

我有两个数据库表。一个用于保存基本数据,另一个用于保存数据历史记录。例如:我有一张桌子books和一张桌子book_data

现在,在books表中我有一个像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);
 }

但是现在,我也希望得到历史记录"的销售。这意味着,当我选择一本书时,我也希望从book_data表中获取所有相关值。因此,当我保存过去4天的数据时,我还希望在我的回复中显示这些数据。

在我的Book模特课中我有

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);
    }
}

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

第1段:对于表现来说这不是很糟糕,因为我首先得到了关系中的所有对象,然后然后我按ID过滤它? 第二:当我传递一个不存在的ID时,不会抛出ModelNotFoundException

那么,我怎样才能实现这一目标,最好的方法呢?两者都是性能和可读性以及最好的情况。

1 个答案:

答案 0 :(得分:2)

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

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

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

如果您使用ModelNotFoundException,则仅会引发findOrFail()find()只会返回null。所以这就是你想要的:

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