Examples of using model validation in Laravel learning tutorial

  • 2021-08-10 07:16:33
  • OfStack

Preface

This article mainly introduces the related content of model validation about Laravel learning, and shares it for your reference. The following words are not much to say, let's take a look at the detailed introduction.

Before writing to database, validation is required for the data, such as type-check for every model column definition ('type', column must be enum('card','loan')) In this case, model event is used.

Write in EventServiceProvider (or customize 1 ValidationServiceProvider):


public function boot()
{
  /**
   * Inspired by @see \Illuminate\Foundation\Providers\FormRequestServiceProvider::boot()
   *
   * Note: saving event is always triggered before creating and updating events
   */
  $this->app['events']->listen('eloquent.saving: *', function (string $event_name, array $data): void {
   /** @var \App\Extensions\Illuminate\Database\Eloquent\Model $object */
   $object = $data[0];
   
   $object->validate();
  });
}

'eloquent.saving: *' Is an saving that represents all model of listen, that is, any write operation of model will trigger this event.

Then write an abstract model extends EloquentModel:


// \App\Extensions\Illuminate\Database\Eloquent\Model

use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Validation\ValidationException;

abstract class Model extends EloquentModel
{
 public function validate():void
 {
  // 1. validate type rules (type-check)
  $validator = $this->getTypeValidator();
  
  if ($validator->fails()) {
   throw new ValidationException($validator);
  }
  
  // $validator = $this->getConstraintValidator();
  // 2. validate constraint rules (sanity-check)
 }

 protected function getTypeValidator()
 {
  return $this->getValidationFactory()->make($this->attributes, static::COLUMN_TYPE_RULES);
 }
 
 protected function getValidationFactory()
 {
  return app(Factory::class);
 }
 
 protected function getConstraintValidator()
 {
  // return $this->getValidationFactory()->make($attributes, static::COLUMN_CONSTRAINT_RULES);
 } 
}

Thus, in every subclass that inherits abstract model, define const COLUMN_TYPE_RULES as follows:


class Account extends Model
{
 public const COLUMN_TYPE_RULES = [
  'id' => 'integer|between:0,4294967295',
  'source' => 'nullable|in:schwab,orion,yodlee',
  'type' => 'required|in:bank,card,loan',
 ];
}

During the write operation, type-check is carried out for every schema definition of model in advance to avoid invalid collision with database. The purpose of this feature is to verify whether the field definition of the input data is valid from model schema.

In addition, in addition to type-check schema definition, sanity-check constraint rules must be logically verified according to business needs. For example, when creating an account, the input field person_id in inputs cannot be an child minor, and so on. The business here is different, and constraint rules is different, so we don't explain too much. The main purpose of this feature is to logically verify the validity of input data.

OK, in a word, under general circumstances, model validation should be done before writing the database to avoid invalid hit db.

Summarize


Related articles: