我有两个数据库表。一个用于保存基本数据,另一个用于保存数据的历史记录。举个例子:我有一个表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
。
那么,我该如何做到这一点,最好的方法?对于性能和可读性和最佳情况。
首先,不需要get()
。您可以单独使用find()
:
$post = Book::with('history')->find($id);
此不查询所有记录,然后进行过滤。它基本上只是为id添加一个WHERE子句,并返回第一个(也是唯一的)结果。
ModelNotFoundException
只在使用findOrFail()
时抛出。find()
将只返回null
。这就是你想要的:
$post = Book::with('history')->findOrFail($id);