CodeIgniter Forums

Full Version: Form Validation Default
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
How can I extend the form validation throughout all my controllers but with a twist:

I have a controller called "article", one of the items that it accepts is a "slug" I would like to do a check and make sure the slug that is used is unique.

I can do this by creating a function in the article controller however I would like to make something more universal which I can call it "slug_check" and use this in multiple controllers. The issue is that I can also extend BUT each has it's own table in the database to check, for example for "article" I need it to check in the "article" table but if we have a "gallery" that also has a slug we need the "slug_check" to check BUT on the "gallery" table.

What is the best way to do this in a fashion where I do not need to create the function each time inside the controller?
I think best practice is to do form validation in models, not controllers, but the solution to your needs is similar. In the case of using form validation in controllers, you would make a MY_Controller.php file and put it in /application/core/. Search for "CodeIgniter MY_Controller" on the internet, and you're sure to see exactly how it is done. Likewise, you would do something similar for the model, but creating a MY_Model.php.
Suggest that you put your validation methods in a model. Then any controller can call the validation method. Also you can make a separate validation methods and call more then one validation method. So you have your basic validation method, and then call your second validation method when needed. And if you are interacting with different database tables then consider putting them in different models. And if you need to call these all the time from different controllers you can autoload the models in application/autoload .
I personally disagree with putting form validations in models. Form validations, as stated, are for forms, which is found in a view which is handled by controllers. Database validation in models is fine, but if you are using your models with different apps without a front end, things can get hairy quickly.

For your case though, you can always build different validation rule as a config file and load it that way. If what you're validation is something you can isolate to specific models, then I'd recommend using a library for validating each model object.
(05-22-2016, 05:23 PM)albertleao Wrote: [ -> ]I personally disagree with putting form validations in models. Form validations, as stated, are for forms, which is found in a view which is handled by controllers. Database validation in models is fine, but if you are using your models with different apps without a front end, things can get hairy quickly.

Wouldn't the apps still be running through a Controller?
So here is why i don't like form validation in Controllers - and (again) these are all personal choices no right or wrong implied. If you need to change a form field or add a field in a form - you have to update the View, update the validation rule in the Controller, and update the fields going to the database in the Model. Thats three different places to build out or do changes. If you make a mistake in your view file maybe the form does not render correctly. If you make a mistake in your controller it can bring everything down. So any changes in the controller are more "costly" to your application.

Versus if you put the validation in the model now you just have two places to do changes. In other words a 'thin' controller handles generalities - not details - so it does not have to change very often.

So we have gone from three to two places. Can we refactor to just one place for our build and future changes? Wouldn't that make it much faster and easier to build and update forms? Yes, the next step is preassembling the form elements (using form helper) into an array that goes to the view. Then almost all the changes are constrained to just the model (or library if you prefer). The View at that point becomes "just a view" with absolutely no responsibilities. I'm just starting to experiment with this and at least so far its amazing in how much easier and faster it is to build out large complex forms and their validation.
Form validation is for data, which ends up in the database, and the queries that put it there are in models. I do believe that's the reason why most people say the model is where form validation belongs. Personally I don't care. I put most of my validation in models, but am guilty of doing some in controllers when I'm being lazy. The beauty of CI is that you can do what you want.
First, I wanted to draw attention to the is_unique rule built into the form validation library. This will tell you if the value of the field already exists in the table/column (requires Query Builder and can only really be used on insert, since the value will exist when you attempt to update the data): http://www.codeigniter.com/user_guide/li...-reference

Second, you can extend the form_validation library by creating a MY_Form_validation class which extends CI_Form_validation. This allows you to add public methods to the validation library which can be used as validation rules anywhere else you happen to be using the form validation library. I use this for rules which are generally handy throughout my site, but not tied to any particular model/controller. Bonfire has a handful of rules defined this way, and I add some of my own in my projects.

Finally, for model-specific validation, I usually store my validation rules in the model, but I perform validation in both the model and the controller. Sometimes I have the controller retrieve the validation rules from the model and apply them to the form, but there may be instances where the controller is dealing with data from multiple models. Validation performed by my controller is specific to the action being taken. Validation performed by my model is specific to making sure my data is safe to put into the database. It's quite rare that I find a reason not to perform data validation on the form, but it does occasionally happen, and in those cases I don't return those specific rules to the controller, but still check them in the model before inserting/updating/deleting data.

If you're a little more paranoid in your model's acceptance of data, you're far less likely to run into issues later if you're using a model in multiple places.
(05-26-2016, 09:49 AM)cartalot Wrote: [ -> ]
(05-22-2016, 05:23 PM)albertleao Wrote: [ -> ]I personally disagree with putting form validations in models. Form validations, as stated, are for forms, which is found in a view which is handled by controllers. Database validation in models is fine, but if you are using your models with different apps without a front end, things can get hairy quickly.

Wouldn't the apps still be running through a Controller?
So here is why i don't like form validation in Controllers - and (again) these are all personal choices no right or wrong implied. If you need to change a form field or add a field in a form - you have to update the View, update the validation rule in the Controller, and update the fields going to the database in the Model. Thats three different places to build out or do changes. If you make a mistake in your view file maybe the form does not render correctly. If you make a mistake in your controller it can bring everything down. So any changes in the controller are more "costly" to your application.

Versus if you put the validation in the model now you just have two places to do changes. In other words a 'thin' controller handles generalities - not details - so it does not have to change very often.

So we have gone from three to two places. Can we refactor to just one place for our build and future changes? Wouldn't that make it much faster and easier to build and update forms? Yes, the next step is preassembling the form elements (using form helper) into an array that goes to the view. Then almost all the changes are constrained to just the model (or library if you prefer). The View at that point becomes "just a view" with absolutely no responsibilities. I'm just starting to experiment with this and at least so far its amazing in how much easier and faster it is to build out large complex forms and their validation.

sure that may work for a small application, but if you work on larger, more complex application where different systems use the same models, the forms might not always be the same.

I've run into this issue several times when developing for companies. It was especially common in Ruby and Ruby on rails. Several companies would have all their models as it's own git repository and have that repo work for multiple applications. At that point, tying a model to a form validation was wrong and we did validation on a per model/db field basis. After learning this in Ruby, I implemented this in my CI apps and have had a ton more flexibility. Now my models might be delivering data to users, services, apis... and I don't have to worry about 'forms'. I can handle all that in the controllers.

In essence, form validation is exactly what it says, form validation which is directly connected to something displayed to the user in a view or an api. A database validation is connected to the database, so that's where you could do field and table constraints on top of the db schema.

Just a different perspective...
Personally I agree with albertleao and would never put validation in a model either. Although I think a lot of these differences come simply from different interpretations of what the different parts of the MVC model are for. But since this is only a pattern people can of course adapt it, interpret it, or use it in any way suitable for the needs of the project in hand.

I often wonder if the MVC pattern itself is no longer adequate or the best fit for web applications. I already use libraries as controllers really, and controllers as supervisors or front-controllers. I also use libraries for templating too, although I think of them as a presentation layer, in an attempt to modularise output and stay as DRY as possible and keep views as php free as possible.

Paul.