I have a question about Laravel validation.
I receive data from a POST request and I want to validate this data. I don't know what is better between a custom request with validation in the custom request class or a normal request (ex: Request $request) with the validation rules specified within the method in the Controller.
Could you please explain what is better?
Thank you so much,
have a nice day.
Validation in the controller is the default situation, so why might you want to move validation into its own form request class? Some considerations;
Cleaner Controller
Reusable validation rules (in practice I rarely find this true).
Push validation of data out more towards the edges of your application so that the controller only has to deal with known good data.
I also sometimes persist data in the form request also. (https://talltips.novate.co.uk/laravel/simplify-laravel-crud-controllers#form-request)
I ran into this issue: our SpringMVC Validator validates a form (the normal case); this works OK.
Also, in a separate use case, it needs to be called remotely from a different location to put an exclamation point icon ("!") in front of some element on a different screen that refers to that form object.
I can validate any object of the class supported by the Validator, but the issue is how to add errors:
1) On the one hand, this Validator should reject errors for the path on its screen when it's used in the normal case:
errors.rejectValue("object.field.path", "errorCode", args, defaultMessage);
2) On the other hand, this will fail when it's called remotely, this path doesn't exist because the form is different. The only thing I can do here is something that doesn't depend on paths,
errors.rejectValue("errorCode");
Ideally the same Validator should respond to both cases... It should tell me there are validation errors on the form. In Case A it's specific, in Case B it's general. Can anyone advise how to approach this?
UPDATE The issue is general Bean Validation vs. GUI Validation. I understand is that SpringMVC's Validators are strongly tied to the GUI. But we also need a generic way to validate data beans, and hopefully reuse that. Or maybe I can create a "mock" BindingResult/JSP?
You can use Model Validation Rules and FormRequest/Request Validaiton Rules.
So there are Scenarios:
Form
Rest Create
Should you use a Model Validation regardless?
Why are there 2 methods?
Laravel provides a powerful Validation class that you can benefit from by using several approaches.
So, you can validate inside the model, and this works best if you need to centralize the logic at the model during creation or update. Also it works if you create Intermediate Models, or creating Models offline, for example Model to hold Reports.
Form Requests is a special way to handle Validation, you can handle the validation inside the Controller, or you can go slim Controllers, and move the Validation elsewhere. Form Requests is better when you are handling complex validation, or if you are using the same validation through different Controllers.
So the Validation class is the same, how you make use of it is up to you.
Laravel version - 5.0.0
Laravel offers so many ways to validate so I cannot choose what to use. Because no one of them suits my tastes.
What I want: full management of validation process. I want a class which:
has got rules property, but it I can modify them any time
can return break validation process if any rule fails; add rules to validator
has got custom messages
communicate with other classes which have got validate method as well as their own messages.
manage redirects and return values
Basically I do not want to extend validation class but simple use it. I think, form requests could do what I want. But now I do not understand their purpose. They are very poor in Laravel. Also, I do not want place all this in controller.
So, the only way is to create a custom class?
It seems like official way to validate models in Laravel 4 is through Validator in Controller? Can somebody point out why is it so?
Wouldn't it make more sense to implement validation in Model?
I prefer the Ardent package for making validation of models as smooth and minimal as possible. To me it makes more sense to have the validation rules in the model as well.
It will return false when $model->save() is called and validation fails, then you can get the error messages through $model->errors()->all() for example.
It does make sense to have validation in the models, but this validation should only be there to make sure you don't save any corrupt data.
The Validator is in the Controller because it's used to handle Input, and generate Output.
If you would do the validation in the Model then you either have to return false, and show the user the most random of error messages about invalid data.
You could also return some kine of array containing all the errors that are generated, but that's something a Model shouldn't do.
Or you could throw an Exception, which is something that should be done when a model tries to consume invalid data, but it kills the application, which is not the wanted solution for a form validator.
When doing the form validation in the Controller, you can do everything you want with the error messages, without changing the purpose of a Model.
And in your model you can do a validation to make sure you didn't make a mistake, which will corrupt your database. Because if this happens the application should shut down.
So to put this in a real answer to your question:
Validation in the model makes sense to avoid corrupt data, but if you want to give feedback to the user about invalid input, it should be in the controller.
I wrestled with this for a while and settled on handling most of my validation in a validation service, based something along the lines of this. I can then have different validation rules based on the context.
As Nico mentions, validation in the model is good to avoid corrupt data, but I prefer thin controllers so I pass the functionality that would sit in controller into the service. This also has the benefit of being able to reuse the validation in different controllers/methods.
Why I prefer In-Model Validation: I've worked with both styles and each have pluses and minuses, but I prefer in-model validation. In our current app I don't see in-controller validation as an option, since we're altering our data in so many places (dedicated forms, inline edit, bulk edit, bulk upload, api, etc). I've never really worked with validation services (though they might be an option) but I personally like to keep logic as close to the model as possible, that way I know another developer won't bypass it. I also don't like adding lots of extra files on top of the MVC and basic Libraries folder because it just seems like more you have to think about organizing properly.
Issues with In-Model Validation: These are some things you need to consider to make In-Model work well. SOME OF THESE ARE ALREADY TAKEN INTO CONSIDERATION BY PLUGINS. I think other frameworks (CakePHP) already deal with these, but Laravel doesn't really.
Values that will be validated but not saved to the db (e.g.,
"accepted_agreement").
Many to many or belongs to many
relationships
Setting conditional defaults (not critical but
might want to think about at the same time)
Various form scenarios - sometimes you might need different validation
depending upon which form submits it. The form reference can be a
purgeable attribute for validation maybe?
How will you get back error messages (all in-model validation plugins handle this for you)
Different validation rulesets. Draft creation vs "real" creation. (Most handle this for you)
Ultimately, for simple applications that don't have lots of ways of interacting with the model, I'd say controller validation may be simpler, other then that I prefer in-model.