Laravel place validation stuff - validation

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?

Related

Where do I put "extra" default fields for a Laravel model?

This question is about the "correct" design pattern, not about functional code. I want to adhere to best-practices and use the right feature in Laravel.
I have a model called Order which contains users' product orders.
Order has several columns, like which product, quantity, etc, and is stored in mysql, with a belongsTo() call to the User model.
When I place an order using the OrderController, I call an outside API that I set up using a Service class.
Here's the main part of the question:
I need to add certain fields that the API requires, but on my end are always the same, so it would make sense to me to pack these into an object of their own and just append that object to the end of my Order data before submission.
So where is the "Best" place to put this extra data? In my model? In a Service class? I'm leaning toward the service class, but that just doesn't feel right.
You have an action that gives a single or a collection of a model. So the best practice for adding some extra data to those results is using JsonResource and ResourceCollection. By using them you can easily add anything you want in the ToArray method.
Lumen doesn't have Illuminate\Http by default but you can add it to your project.
Official Http package of laravel
Eloquent: API Resources Documentation.

Why are there 2 ways to Validate in Laravel 5.1?

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 4 Model validation vs Controller validation

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.

Where to implement cross-entity-validation?

I have a project where the data-model and business-layer are located in two different modules. Of course, the bussiness-module has a dependency to the model-module. The entity-validation is implemented through java-validation-api annotations.
I'm wondering where I should implement the cross-entity-validation (business validation, where the relations between different entity types are validated). Currently I see the follwing options:
Create custom javax.validation.ConstraintValidators and associated annotations. Problem is, that the validator would need access to the business-services, i.e. to retrieve related entities, but the model-module should not have a dependency to the business-module.
Implement cross-entity-validation in the business-services persist/merge-methods (i.e. by using interceptors). That would be possible, but the cross-entity-validation is seperated from the entity-validation and I would like to have only one place for validation.
Which option is preferable? Are there any better suggestions?
Thanks,
Sebastian
From the ideological point of view approach 1. is better. Bean Validation is working at the level of Model (in Model-View-Controller) and it is nothing wrong if Model part talks to database. So, for instance, you can create DAOs, which can be used both by service leayer and Model validators in order to avoid code duplication.
Interceptors are also good place to validate something, but you will not be able to use full power and automaticity of Bean Validation. Probably you will need to call validate method on your model objects by hand, throw ConstraintViolationException where needed, etc. Doable, but a little bit of work. In addition some validation probably will be left in Model, so, as you've pointed out, there would be more then one place, where validation is going on.
So I would move necessary DB code to separate layer and go with option 1.

Can I use MVC validation attributes within a custom model binder?

I have lots of MVC validation attributes on my model. Everything works great when the defaultModelBinder binds my model on submit. But, I need to create a custom modelbinder. I'd like to continue using my validation attributes. Can I? If so, how?
I'm not sure whether this is possible or not, but one thing I can say is that if it is possible then the extension points for default model binder don't make it very discoverable. I spent several hours one day trying to get this to work to no avail.
In lieu of getting this to work, you can use the Controller's TryValidateModel() methods.

Resources