如何在没有要验证的特定属性的情况下验证 post 请求

How to validate a post request without a specific attribute to validate

我有一个时间跟踪应用程序,每次要添加新的时间条目时,我必须首先验证所有以前的时间条目是否已关闭(意味着已设置结束日期)并抛出和使用 validate() 方法的错误消息。

我不知道这有多可行或如何去做,阅读文档似乎大多数客户规则都要求提供一个属性,但在这种情况下,更多的是验证逻辑要求而不是post 请求的形式。

当我收到 post 请求时,我会获取所有在 post 请求开始时间之前且尚未指定结束时间的先前时间条目。

理想情况下,如果我得到任何时间返回的条目,我会抛出一个错误说 'You need to close the previous time entry before opening a new one'。

为了更清楚,这是我想在代码中做的事情:

$timeEntry= new TimeEntry;
$openTimeEntries = $timeEntry->Where('start_time', '<', $request->startTime)->Where('end_time', 0)->get();
$count = $openTimeEntries->count();

$request->validate([
    'comment' => 'string',
    'candidateId' => 'required',
    'startTime' => 'required|date',
    'endTime' => 'date|nullable|after:startTime',
    'CustomeTimeEntryRule' => $openTimeEntries->count() > 0, // If false I want this rule to add the message to the validate error array
]);

你走在正确的轨道上。

但是,如果您真的要自定义验证,您应该为 here 创建一个请求,您可以阅读更多相关信息。

只需调用php artisan make:request TimeEntryStoreRequest

public function rules()
{
    return [
       'CustomeTimeEntryRule' => $openTimeEntries->count() > 0,
    ];
}

/**
 * @return array|string[]
 */
public function messages(): array
{
    return [
        'CustomeTimeEntryRule.*' => 'Custom message',
    ];
}

但是,如果它不是来自用户的表单输入,我认为你应该在你的控制器中而不是在表单中检查它。

您也可以像这样简化代码:

use App\Models\TimeEntry;

$openTimeEntriesCount = TimeEntry::select('id')->where('start_time', '<', $request->startTime)->where('end_time', 0)->count();

一个简单的方法是将自定义属性合并到请求中:

$timeEntry= new TimeEntry;
$openTimeEntries = $timeEntry->Where('start_time', '<', $request->startTime)->Where('end_time', 0)->get();
$count = $openTimeEntries->count();

$request->merge([
        'CustomeTimeEntryRule' => $count,
    ]);

然后我们可以使用 in 规则验证属性,这将 return 自定义验证消息,我们可以将其指定为第二个参数,当计数不等于 0 时:

$request->validate([
    'comment' => 'string',
    'candidateId' => 'required',
    'startTime' => 'required|date',
    'endTime' => 'date|nullable|after:startTime',
    'CustomeTimeEntryRule' => 'in:0',
], [
    'CustomeTimeEntryRule.in' => 'You need to close the previous time entry before opening a new one' 
]);