Reputation: 2868
I'd like to use sweet Laravel model binding and then run some complex validation checks on the model itself.
Something like
Route::post('/do-something/{something}', 'SomeController@store');
and
$request->validate([
'something' => [
new MyFirstVeryComplexRule,
new MySecondVeryComplexRule,
new MyThirdVeryComplexRule,
//...
],
]);
I assume, that $value
passed to each rule will be an instance of App\Something
class.
Is is possible to achieve that?
The closest option I can think of is to pass id
of a model and then run App\Some::find($value)
in each rule instance, but this kills the performance and is not scalable.
Answer
No, this is not possible because of x,y,z, try a,b,c
will also be accepted.
Upvotes: 0
Views: 2149
Reputation: 3855
From Laravel's Routing documentation:
Alternatively, you may override the resolveRouteBinding method on your Eloquent model. This method will receive the value of the URI segment and should return the instance of the class that should be injected into the route:
class YourModel {
public function resolveRouteBinding($value, $field = null)
{
return $this->where('name', $value)->firstOrFail();
}
}
You can use this just like @Chin Leung does:
class YourModel {
public function resolveRouteBinding($value, $field = null)
{
$instance = Model::find($value) ?? abort(404);
$validator = Validator::make([
'something' => $instance,
], [
'something' => [
new MyFirstVeryComplexRule,
new MySecondVeryComplexRule,
new MyThirdVeryComplexRule
]
]);
if ($validator->errors()->any()) {
// perform on error tasks
}
return $instance;
}
}
Upvotes: 0
Reputation: 14921
You could create a custom binding in your RouteServiceProvider
like this:
public function boot()
{
parent::boot();
Route::bind('something', function ($value) {
$instance = Model::find($value) ?? abort(404);
$validator = Validator::make([
'something' => $instance,
], [
'something' => [
new MyFirstVeryComplexRule,
new MySecondVeryComplexRule,
new MyThirdVeryComplexRule
]
]);
if ($validator->errors()->any()) {
// perform on error tasks
}
return $instance;
});
}
Then the $value
of each rule will receive the instance of your Model.
For more information, you can take a look at Customizing The Resolution Logic under Route Model Binding: https://laravel.com/docs/5.8/routing#route-model-binding
Upvotes: 1