There have been a couple of discussions regarding the location of user input validation:
Should validation be done in Form objects, or the model?
Where do you do your validation? model, controller or view
These discussions were quite old, so I wanted to ask the question again to see if anyone had any fresh input. If not, I apologise in advance.
If you come from the Validation in the Model camp - does Model mean OOP representation of data (i.e. Active Record/Data Mapper) as "Entity" (to borrow the DDD terminology) - in which case you would, I assume, want all Model classes to inherit common validation constraints. Or can these rules simply be part of a Service in the Model - i.e. a Validation service? For example, could you consider Zend_Form and it's validation classes part of the Model? The concept of a Domain Model does not appear to be limited to Entities, and so validation may not necessarily need to be confined to this Entities.
It seems that you would require a lot of potentially superfluous handing of values and responses back and forth between forms and "Entities" - and in some instances you may not persist the data recieved from user input, or recieve it from user input at all.
I much prefer to put validation in the model, personally. Security considerations of course are beyond the scope of what a model should be used for, but nothing says that a model is updated in exactly one place by exactly one form. By putting type validation and sanity checking outside the model, you have to validate every time you set anything on it, which leads to copy/pasted code that's difficult to update.
I use Zend_Form as part of my models - models are creating the Zend_Form objects. I go this way because Zend_Form is not about the form rendering only; backed up with Zend_Validate and Zend_Filter it is a very powerful tool (my fav from the ZF stack). Matthew Weier O'Phinney wrote a nice post about using Zend_Forms in models: http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html
Data validation should be on its own, called by the controller just before committing to the model.
Haven't used PHP and haven't worked with Zend framework (have heard though), but I really like Jimmy`s blog post about validation from domain driven design perspective.
I considered many different approaches of data validation, and decided that best way of validation - it's validation before entity creation, since validation it's something which can be very dependent from context, and entity itself should not perform validation, because entity should always be in valid state.
So maybe best approach - use separate validation classes to validate data before passing it to entity constructor.
When handling user input, you should definitely handle all logic-oriented validation outside the model.
The model doesn't care about your business logic. The model doesn't care if your start date is after your end date - all the model cares about is that the date is a valid entry for that particular field in the database. It checks the data, sees a properly formatted date and moves on to the next one, because the model's entire realm of responsibility is to ensure the smooth flow of data to and from a data source.
Classes like Zend_Form are nothing more than abstractions of your view.
Related
one "simple" question: http://mwop.net/blog/2012-07-02-zf2-beta5-forms.html
is it possible to use the zf2 zend form annotation validation rules without using zend form, so i can share the validation rules between a model validator (e.g. using for check if the model is correct before persisting it) and the zend form validation?
if my "name" should be not empty and between 5 and 20 characters, it is the same rule for the form and the model.
i hope i pointed it out clearly
Roman
Well, since all data that the models are getting would be from user input or the database, you shouldn't need to test the models itself, too. THe data inside the database should be correct!
IE: trust your own data but not the users?
But if you still wanna do that, i guess you could build the form with the AnnotationBuilder, then get the InputFilters from the Form (im sure there's a method, maybe on per-element-basis) and then use those inside your models - but as my first paragraph implies, i see this as a quite useless point :)
As for multi usable input filters, best thing would be to write own classes extending Zend\InputFilter\InputFilter on a per model basis. When you build your form then you can attach that class as the filter definition via $form->setInputFilter($myModelInputFilterClass) and you could also call that class inside your models to run your data through those filters. I haven't done this manually but it should work.
The only pitfall i guess might happen if you run into required statements. Checking on a per element basis, i don't know if that will work, too. As the InputFilter checks against all given filters. Though if you import a full CSV-Sheet or something you'd have a populateFromCsv() function or something that then checks all data anyways i guess.
I am building a PHP application with a domain layer and a mapper layer and I need to decide where to validate user input. Most validation will be done against a Zend_Form instance. (Per tutorials from Matthew Wierer O'Phinney I am viewing the validation aspects of Zend_Form as belonging to the model).
It seems to me that the two options are:
In the domain layer upon user input. For example, upon new user($_POST), the __construct() method would validate $_POST against the input form
In the mapper layer upon persisting the data. For example, the $userMapper->insert($user) method would validate $user against the input form
My sense is that the validation should be handled in the domain layer, since validation rules are often driven by business rules. Having said that, I could be missing something, and since it's a major design decision, I am hoping for your input.
In addition to the model validation, I have database constraints at the back end and am planning JS validation to improve the user experience!
Thanks for your input!!!
I don't see anything really wrong about doing some validation in the domain model, however you might be doing yourself a disservice.
If you start having to build a larger number of domain models you will likely find yourself rewriting the same validation code over and over again. It might to your benefit to have a service model provide the validation.
That way as you add domain models you just pass the data through the validation service and you can add and remove validators in one place for all of your models. You may also find that some of the validators the ZF already provides are enough.
just my opinion... Good Luck
I develop most of my web applications using CodeIgniter, and have always took the approach of validating form data inside the controller, using the built in Form Validation class, before sending this data to the Model to be used, e.g insert the data into the database.
However, I keep hearing the "skinny controllers, fat models" line - and I'm wondering if these validation checks should be placed inside the model.
Three things strike me when I think of using this approach.
How can different error messages be shown to the user, without returning seemingly ugly arrays or objects from these model functions? e.g A duplicate email on signing up for an account. Would the method responsible for adding a user in the model have to return an array or object to indicate if the insert was successful, and any error messages?
By doing the validation checks in the model, checking variables supplied to the methods from the controller (not POST data), I will lose the use of the Form Validation class, a class that I find very useful in my projects. Would you suggest that I write a class, or library that can be used like a CI library to mimic the Form Validation class, but for supplied variables, and not limited to the POST data?
Following on from that concern...as the POST data would have to be validated for existence (isset($_POST['myvar'])) before being passed to the model, should the rest of the validation not just be placed in the controller as well?
Any suggestions, advice, opinions will be appreciated!
Your original issue comes from fact that CodeIgniter's interpretation of MVC is quite appalling. This framework pretends that View is just a template, and Model is just an ORM ( which some say, should be classified as anti-pattern ). Which is completely wrong, and forces bot business and presentation logic inside the Controller.
But lets leave View aside.
Model in MVC is not a class or an object. Model is a layer, which contains all the business logic. It is actually comprised of instances from multitude of classes. The two most prevalent groups are Domain Objects [1] [2] (this is, what people people usually call "models") and object responsible for information storage and retrieval - usually DataMappers. The model layer also contains standalone components (both your own and 3rd party) and higher level abstractions - services.
What you have as Validation class, might be considered to be a standalone component, which can either be used by Domain object to perform validation, or expect a Domain object to be passed in for validation .. depends on your implementation.
In your situation i would handle this at the service layer. Which would either provide the instance of View class with a valid domain object, or an object, which represents the error.
Some reading materials yu might be interest in:
GUI Architectures
AnemicDomainModel
Tell, Don't ask
Then again .. what the hell i know of it all ..
Controllers are there in MVC pattern to process user input and output. So, input validation and response preparation should be done in a controller.
For instance, I have a controller method "save" which:
looks for input data
runs a validator on the data
if inputs are valid, loads an appropriate model, sets its fields to input values, and calls its save() method
if inputs are invalid, prepares data to re-load the edit form, shows the form
All this sequence creates quite a mess of linear code. I'd like to separate it somehow. Do I move the validation part to a model? Sounds wrong? Do I create a special "library" class to handle inputs?
In Asp.Net MVC this would be better as they have implemented the "object binder" pattern. Hence, the validation and model field binding goes away and controller gets much lighter. Is there something similar for CodeIgniter?
It is not widely accepted that controllers do validation, I do them in model as per "keep your models fat, controllers thin and views dumb".
It depends on the business logic what is a valid phone number and so on, so it only makes sense for me to have it in model.
I would do exactly as you have eluded to and put as much logic into your models as possible. Controllers really should, imo, be used for initiating services and preparing data for views.
You should as much code reusable, ie validators, filters etc..
This is a quick question relating to Symfony, but could be a general MVC question.
I have a class in my model, for example, WebUser. This class has a property of email_address. This value must be unique to each WebUser.
Now, I've made it so all my Symfony forms validate that the email_address is unique for the given WebUser, however I'm wondering if I should add this validation to the model as well?
But this also got me thinking, should you actually validate every set() method in the model? It seems a wise enough decision to make sure no erroneous data ends up in the database, however most (if not all) data has to go through the controllers, which validate as well. So to me it seems I'm running the same validation twice and it just seems pointless?
What are your thoughts on this? I'm still leaning towards validation in the model as that makes the most sense as it dictates the business logic.
If you should validate in the model, how do you throw an appropriate set() error in Symfony that is handled correctly by the form framework?
Thanks.
I disagree with "Validation should be part of domain logic, not front-end logic".
Validation is a complex functional part of your application and must be context aware. ie. you have to know is the user is logged in, what kind of credentials she has, the status of the request/form and so on. Models instead must be context agnostic (to work in any environment not only http request but also cli etc.) so they don't know about the user, the state and the http request. This is a strong requirement for the testability of your model classes.
For the summentioned reason functional validation must belong to the form which knows the application state (ie. session). symfony helps a lot with the sfValidator* classes which belongs to the form component indeed. That's the reason why forms are tested with functional testing.
Data validation should be in the model instead (ie. check if the value is an integer or a string, check if it's null and so on). This is easily accomplished with the Doctrine in-schema validation rules.
I can't speak specifically to Symfony, but I know that I purposely shun Zend Framework's form validation, and instead validate on my models (Zend Framework does not provide its own Model component, so it has no actual opinion on the matter).
There's nothing wrong with validating on the form, but I think you should also be validating on the model. Validating on the form might be useful for quick and easy input checking, especially if the processing logic is complex - you won't waste time working with data that's obviously bad.
Reasons I think model validation is best:
There's a chance a model will alter the data after it passes through the form and before it goes into the DB
Validation should be part of domain logic, not front-end logic (I realize Symfony seems to disagree).
Validation state travels with the model object, instead of the form object.
If you're not totally sold validating only in the model, a combination of the two sounds like a good solution.
EDIT: At the end of the day, it might make the most sense to just go with your framework on this. If Symfony seems most opinionated toward validation in the controller, and doesn't provide an easy path for validation in the model, just go with what they want you to do (or the direction in which the Symfony community leans). Fighting your framework is never fun.
I can't help out with the symfony part but most MVC-Frameworks do validation in the model, since this is the only place inside a MVC environment where validation should be.
This goes for the validation of the model's attributes of course.
I Think You Should User MVC Validator Tool Ket Insted of using others rely on modelstate its easyer and also testable and its based on formcollected not to the model that give you free run way
Regards MArwan HAfez