Tengo una aplicación de seguimiento de tiempo en la que cada vez que se va a agregar una nueva entrada de tiempo, primero debo verificar que todas las entradas de tiempo anteriores se hayan cerrado (lo que significa que se ha establecido una fecha de finalización) y lanzar un mensaje de error usando el método validar().
No sé qué tan factible es esto o cómo hacerlo, al leer la documentación, parece que la mayoría de las reglas personalizadas requieren que se proporcione un atributo, pero en este caso se trata más de validar los requisitos lógicos que la forma de la solicitud posterior. .
Cuando recibo una solicitud de publicación, busco todas las entradas de tiempo anteriores que vienen antes de la hora de inicio de la solicitud de publicación y aún no se les ha dado una hora de finalización.
Idealmente, si obtengo alguna entrada de tiempo arrojaría un error que dice 'Debe cerrar la entrada de tiempo anterior antes de abrir una nueva'.
Para mayor claridad, esto es lo que quiero hacer en el código:
$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 ]);Estás en el camino correcto.
Sin embargo, si realmente personaliza la validación, debe crear una solicitudaquí . Puede leer más al respecto.
Simplemente llame a php artisan make:request TimeEntryStoreRequest
public function rules() { return [ 'CustomeTimeEntryRule' => $openTimeEntries->count() > 0, ]; } /** * @return array|string[] */ public function messages(): array { return [ 'CustomeTimeEntryRule.*' => 'Custom message', ]; }Sin embargo, si no es una entrada de formulario de un usuario, creo que debería verificarlo dentro de su controlador, no en el formulario.
También puedes simplificar tu código así:
use App\Models\TimeEntry; $openTimeEntriesCount = TimeEntry::select('id')->where('start_time', '<', $request->startTime)->where('end_time', 0)->count();Una forma sencilla de hacer esto es combinar el atributo personalizado con la solicitud:
$timeEntry= new TimeEntry; $openTimeEntries = $timeEntry->Where('start_time', '<', $request->startTime)->Where('end_time', 0)->get(); $count = $openTimeEntries->count(); $request->merge([ 'CustomeTimeEntryRule' => $count, ]);Luego podemos validar el atributo usando la regla in , que devolverá un mensaje de validación personalizado que podemos especificar como segundo argumento, cuando el conteo no sea igual a 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' ]);