出于验证目的,我在自定义请求文件(ClientAsocCardRequest)上有两个自定义规则
public function rules()
{
return [
'code' => ['required', 'bail', 'size:20', new QRCodeAvailability()],
'client' => ['required', 'bail', 'integer', 'min:1', new CardAsocAleardy()],
];
}
1个QRCode可用性
...
public function passes ($attribute, $code) {
$qrcod = QRcod::find($code);
...
2张CardAsocAleardy
...
public function passes ($attribute, $clientid) {
$client = Client::find($clientid);
...
前面的代码在数据库上生成两个查询。在控制器代码中,我有:
...
public function asociatecard(ClientAsocCardRequest $request) {
$qrcode = QRcod::find($request->code);
$client = Client::find($request->client);
...
现在,前面的代码在相同的请求流上生成相同的查询。因此,如果我需要在之前检查客户端和qrcode雄辩的实体,并且之后也需要在控制器上使用相同的实体;如何减少生成的查询数量。
答案 0 :(得分:1)
这是一个选择:
注意:目前我找不到确切的代码,但是可以执行类似的操作。没有测试代码,但是我写了一个想法。
public function action(Request $request) {
$validator = $this->getValidationFactory()->make($request->all(), [
'id' => 'required|int'
]);
if(! $entity = Model::find($request->input('id'))) {
$validator->getMessageBag()->add('id', 'Wrong id');
throw new \Illuminate\Validation\ValidationException($validator);
}
// Do action on $entity.
}
另一个选择:
您还可以静态使用ValidationException。这样
1-您可以将Request
类用于其余的验证规则。 (我不喜欢,因为您的规则崩溃了。)
2-或使用$this->validate($request, ['rules'])
代替getValidationFactory()
和getMessageBag()
。
public function action(Request $request) {
$validator = $this->validate($request, [
'id' => 'required|int'
]);
if(! $entity = Model::find($request->input('id'))) {
throw new \Illuminate\Validation\ValidationException::withMessages([
'id' => ['Wrong id']
]);
}
// Do action on $entity.
}
答案 1 :(得分:0)
IMO没有其他方法可以对数据库进行验证而不进行查询。如果您的目标是减少查询调用,那么唯一的方法可能是使用简单的if
来完成。顺便说一下,Laravel已经提供了验证规则,用于检查数据库中是否存在具有字段值的特定记录。您可以遵循此documentation。因此您的规则应如下所示:
return [
'code' => ['required', 'bail', 'size:20', 'exists:qr,id'],
'client' => ['required', 'bail', 'integer', 'min:1', 'exists:clients,id'],
];