I have this code:
class BunnyUpdateRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'id' => ['required', 'min:1'],
'status' => ['required', Rule::enum(BunnyStatus::class)]
];
}
public function validationData(){
return array_merge($this->all(), [
'id' => $this->route()->parameter('bunny_id'),
'status' => $this->route()->parameter('status')
]);
}
}
class BunnyController extends Controller
{
public function update(BunnyUpdateRequest $bunnyUpdateRequest)
{
$fields = $bunnyUpdateRequest->validated();
$bunny = Bunny::findOrFail($fields['id']);
if ($bunny->status === BunnyStatus::Done)
return Response::json(null, 422);
$bunny->status = $fields['status'];
$bunny->save();
return Response::json(null, 200);
}
}
Normally I would use $request->input
to get the validated body input field or query param. As far as I understand validation runs in this case. At least I hope so. The upper code gets path params which are empty if I try to get the same way. This is why I used the validated()
array. I don’t like this approach, because I find the code ugly. Is there a way to get these path params as object properties on the request object just as body input fields and query params? Is there a way to get a Bunny instance instead of the id with request model binding somehow?
2
Answers
I have a solution:
Instead of using the
validationData
method I use theprepareForValidation
to merge the path params. I movee thefindOrFail
to the request. It gives 404 for a non existent bunny this way too.1st of all the answer you provided is good one, from the conventional point of view i.e. you fetched the two parameters from the
URL
then validated (using customForm Request
) and updated the records ifBunnyStatus
not equal toDONE
.But Laravel itself provides some in built features with which you can do the same operation with lesser lines of code as well as without custom
Form Request
.That is the reason I am writing this answer which will provide another perspective to do the same and also help you to manage
404 error
automatically.Change Your Route defination like this.
Above I have implemented
implicit model binding
,implicit enum binding
along withmissing model/enum Behaviour
.That is the reason you will not need customform request
becausebasic-validation
will be done there.Then in the Controller do this. This will by default fetch & injected to the
update()
method the matching model instance of theBunny
model asBunny $bunny
&BunnyStatus $status
as Enum passed to theURL
after validation that is being done in the Route defination.Remember to import these class and also the orther required class to the top of the Controller class.
Citation:-