Reputation: 16283
There's much debate about where validation belongs in a Laravel application. Especially when things get complicated. Personally, I believe it should be the Model's job to only accept valid data and throw Exceptions when it receives something invalid.
With that in mind I would like to propose the following scenario for a User model (I'm working on something like this at the moment):
There are loads of options available, some feel easier to implement but feel wrong:
Option 1: Controller validation. Sticking the validation in the controller(s) that handle this object is easy to do. On the other hand rules are repeated all over the place and this feels like a bad way to go about it.
Option 2: Form validators. Creating separator validators for the different forms. Essentially, this is more or less the same approach as option 1, but we have just extracted the validation to separate classes. Rules are still repeated in various different places and still feels dirty.
Option 3: Entire Model validation. Adding the validation rules to a model and validating before saving (Either by explicitly calling a validation method from the controller or validating on save). Feels much better but still has drawbacks due to the complexity of the scenario. We would need to deal with excluding IDs in unique rules for existing records. We would need to deal with password hashing before saving to database (If we'd loaded a record from a database, the model would contain a hashed password that really, we shouldn't validate). We would still have to deal with the cropping/resizing/moving of an uploaded image and generating a unique filename somehow.
Option 4: Model validation/processing function. Write a function that accepts data and validates it (Throwing exceptions if invalid) before setting attributes. Only validates the data it is provided with (We may only pass in a new profile image for example). Dynamically adjusts rules based on whether the object exists or is a new object. Calls relevant processing functions for example a function that would deal with resizing/cropping/moving an uploaded image and deleting the old profile image.
Option 5: Model mutators. Write mutators that are responsible for validating and processing the fields they represent. This ensures that only valid data could get into the model and all processing is done. Errors could be handled either by instantly throwing exceptions or by keeping track of problems using an errors field which could then be retrieved. Drawbacks could be that if a field is not set, then validation for that field is never called, and therefore some empty required fields could slip through the net - I suppose this could be remedied by making sure in the controller that all input is passed through.
Option 6: Model mutators + Entire model validation. Model mutators as previously described in option 5 with the addition of validating the entire model before saving the data like in option 3. This would make sure no empty required fields slip through the net.
Any suggestions?
Please note, I'm not after any code help. Just looking for suggestions and recommendations on how to go about a complex scenario in the best way.
Cheers
Upvotes: 2
Views: 2580
Reputation: 60048
Laravel 5 provides Form Request Validation - which is a great way to handle validation now. All rules are kept in one location, and it follows DRY and SRP principles.
They give you the ability to contain complex validation, yet also do simple requests very quickly.
Most importantly it abstracts the validation away from the controller - so it can be used in multiple places. If the validation fails - then the controller is never even called - so your controllers start to clean up really fast.
Upvotes: 7