我有两个数据库表。一个用于保存基本数据,另一个用于保存数据历史记录。例如:我有一张桌子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
。
那么,我怎样才能实现这一目标,最好的方法呢?两者都是性能和可读性以及最好的情况。
答案 0 :(得分:2)
首先,不需要get()
。您可以自己使用find()
:
$post = Book::with('history')->find($id);
此不会查询所有记录并在之后进行过滤。它基本上只是为id添加一个WHERE子句并返回第一个(也是唯一的)结果。
如果您使用ModelNotFoundException
,则仅会引发findOrFail()
。 find()
只会返回null
。所以这就是你想要的:
$post = Book::with('history')->findOrFail($id);