Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

dancourse's avatar

Form Validation or Model Validation?

So I've got a model with rules written into it. Should I be using those to validate form entry or creating a whole other Form Validation class to carry out the validation per. form?

Thanks!

DanC

public static $rules = [
        'name'      => array('required', 'min:5', 'max:30'),
        'email'     => array('required', 'min:5', 'max:90', 'email', 'unique:users'),
        'password'  => array('required', 'min:5', 'max:30'),
        'regions'   => 'max:4'
    ];
0 likes
6 replies
RachidLaasri's avatar

You can use the same rules on edit/insert the same resource, no need to create another class.

you can use your rules like :

$validation = Validator::make(Input::all(), $rules);

if ( $validation->fails() ) 
{
    $errors = $validation->messages();

    // redirect back with input & errors.
}

// insert to the DB, or do whatever you want. 

1 like
devinfd's avatar

Which version of Laravel are you using and is this for a big application or a little one?

In my opinion, If your using L5 then I would just use the built in form classes. If this with L4 and a smaller app then just use your model rules. Basically keep it simple and understandable so that a year from now you'll know what's going on.

2 likes
ATOM-Group's avatar
Level 11

Model validation and form validation are separate concepts, and you should have both in place.

Models should validate their own data to make sure they're not setting garbage into the database or being malformed. But a form is not necessarily tied to a model 1:1, and thus it needs its own validation to validate user input (e.g. conditional / dynamic fields, compared fields, the state of another model or object in the request etc...).

As RachidLaasri said, you can re-use some of the same validation rules, but you may also need custom form validation rules as well. You will also likely want to specify custom validation messages, which should not necessarily be defined in the model, as the wording can be specific to form's context.

Since I value consistency over efficiency, I ALWAYS validate with a form validator, even if the form is in fact a 1:1 map to a model. It's shitty when some forms rely on model validation, while others rely on form validation. So given that, I would always create a form validation class that has its own rules as applicable, but then also allows you to bind any number of models to validator that uses array_replace to merge each models' rules in with the rules explicitly defined for the form. That will at least save you from duplicating the rules.

Here's a Gist with a quick and dirty validation wrapper that combines the rules and messages from the form, and any relevant models. This will likely need modification - totally untested, but you get the idea.

4 likes
nolros's avatar

Agree with @tag do both - form validation, but you should also be doing model validation. How much model depends on size of application, data integrity requirements, etc. However, you can do a fair amount with just class constructors in model. Jeff OOP series helped me a ton with these concepts. I find that model validation helps build better coding discipline, whereas FormBuilder validation by itself leads to loose coding.

very! rough example of model integrity with class constructors

class MyClass {

    protected $select = array();  
    protected $guest = 0;     
    protected $name = 0;     

    public function __construct( $select = null, $name = null )
    {
        if ( ! is_array( $select ) )
        {
            throw new \InvalidArgumentException('Constructor expects either no arguments or an array as a first argument' );
        }

        if ( count( $select ) > ( 30 >> 1 ) )
        {
            throw new \InvalidArgumentException( 'Select can have a maximum of 30 values' );
        }
        if ( ! is_null( $name ) )
        {
            if( !is_string( $value ) )
            {
                throw new \InvalidArgumentException(  'Constructor second argument, name, must either be string'  );
            }
            elseif ( $value === 'guest' )
            {
                $this->value = $this->guest; // user has logged in as guest
            }
            elseif ( is_string( $name ) )
            {
                $this->__set( $name, true ); /// magic __set and __get methods (loving them)
                }
            else
            {
                throw new \InvalidArgumentException( 'Constructor second argument must either be a name'  );
            }
        }
    }
    // all your other class methods
}
1 like
dancourse's avatar

Holy cow this is a good forum! Thanks for your help all, everyone had some very good insight.

dancourse's avatar

I realise I was totally struggling with trying to make one size fit all, however, most forms are not 1:1 with the model. @jeff_way should totally do a vid on that. Maybe he would cover validating relations too, that was something I spent ages searching for when I first started on the "digging in" series. Cheers again.

2 likes

Please or to participate in this conversation.