I have a Form where a timeslot
(the validating field) might be valid for employee A
(another field in the component), but not for employee B
.
I have a custom validation Rule TimeSlotEmployee
that checks for the correctness of the combination (employee, timeslot)
through request('employee_id')
and the $value
parameter of the passes
function, and so far it works fine.
I'm now moving this form into a Livewire component, but I'm facing difficulties because in the POST request that is triggered by the update of the timeslot
field there is no employee_id
, only the new timeslot
value.
How can I solve this problem? Am I tackling it from the wrong angle?
Update
This is the rules
function inside the TimeSlotRequest
:
public function rules()
{
return [
'employee_id' => ['required', 'numeric'],
'timeslot' => ['required', new TimeSlotEmployeeRule()],
];
}
In the TimeSlotEmployeeRule
, this is the passes
function:
public function passes($attribute, $value)
{
$timesloteValue = Carbon::createFromFormat('d-m-Y H:i', $value);
$employee = Employee::find(request('employee_id'));
// perform checks: this part works, but requires the employee instance
return true;
}
In the Livewire component, I use the standard updated
method:
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
Since the request in Livewire needs to rehydrate the component, you can never fully depend on the request()
helper, particularly in subrequests - as the data being passed is Livewire's data.
You should pass the value as a parameter to the rule instead, like so,
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class TimeSlotEmployeeRule implements Rule
{
public int $employee_id;
public function __construct($employee_id)
{
$this->employee_id = $employee_id;
}
public function passes($attribute, $value)
{
$timesloteValue = Carbon::createFromFormat('d-m-Y H:i', $value);
$employee = Employee::find($this->employee_id);
// perform checks: this part works, but requires the employee instance
return true;
}
}
Then in the rules, you pass in the ID,
public function rules()
{
return [
'employee_id' => ['required', 'numeric'],
'timeslot' => ['required', new TimeSlotEmployeeRule($this->employee_id)],
];
}