Laravel form validation is unique using two fields

How can I get a unique validation rule for 2 fields?

and. The application should not allow two people to have the same name and surname.

Allowed users to fill in only the first name or only the last name. Because the user can have only one of them.

b. But if the user enters only the first name (Glen), no other person in the table should have the same (first name = 'Glen' and last name = null). another "Glen Smith" is good.

I tried the following rule. It works fine when both fields (first and last name) are not null:

'firstName' => 'unique:people,firstName,NULL,id,lastName,' . $request->lastName

This rule does not work on b. when there is only one field.

Any clues?

+12
source share
4 answers

The built-in validator uniquewill not really support what you are trying to do. The goal is to make sure that the only valid unique in the database, and not a composite of two values. However, you can create a custom validator :

Validator::extend('uniqueFirstAndLastName', function ($attribute, $value, $parameters, $validator) {
    $count = DB::table('people')->where('firstName', $value)
                                ->where('lastName', $parameters[0])
                                ->count();

    return $count === 0;
});

You can then access this new rule with:

'firstName' => "uniqueFirstAndLastName:{$request->lastName}"

You may have to tweak the database query a bit, as it has not been tested.

+13
source

This is an extensive answer to this question and how to create a regular laravel validator as a whole, you can simply copy and paste and try to understand later: Step 1 . Create provider app / Providers / CustomValidatorProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator as ValidatorFacade;

/**
 * Provider for custom validators. Handles registration for custom validators.
 * 
 * @author Aderemi Dayo<akinsnazri@gmail.com>
 */
class CustomValidatorProvider extends ServiceProvider {

    /**
     * An array of fully qualified class names of the custom validators to be
     * registered.
     * 
     * @var array
     */
    protected $validators = [
        App\Validators\MultipleUniqueValidator::class,
    ];

    /**
     * Bootstrap the application services.
     *
     * @return void
     * @throws \Exception
     */
    public function boot() {
        //register custom validators
        foreach ($this->validators as $class) {
            $customValidator = new $class();
            ValidatorFacade::extend($customValidator->getName(), function() use ($customValidator) {
                //set custom error messages on the validator
                func_get_args()[3]->setCustomMessages($customValidator->getCustomErrorMessages());
                return call_user_func_array([$customValidator, "validate"], func_get_args());
            });
            ValidatorFacade::replacer($customValidator->getName(), function() use ($customValidator) {
                return call_user_func_array([$customValidator, "replacer"], func_get_args());
            });
        }
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register() {
        //
    }

}

2: app.php config/app.php,

App\Providers\CustomValidatorProvider::class,

3: , validator app/Validators/MultipleUniqueValidator.php

<?php

namespace App\Validators;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Illuminate\Validation\Validator;

/**
 * Multiple field uniqueness in laravel
 *
 * @author Aderemi Dayo<akinsnazri@gmail.com>
 */
class MultipleUniqueValidator{

    /**
     * Name of the validator.
     *
     * @var string
     */
    protected $name = "multiple_unique";

    /**
     * Return the name of the validator. This is the name that is used to specify
     * that this validator be used.
     * 
     * @return string name of the validator
     */
    public function getName(): string {
        return $this->name;
    }

    /**
     *
     * @param string $message
     * @param string $attribute
     * @param string $rule
     * @param array $parameters
     * @return string
     */
    public function replacer(string $message, string $attribute, string $rule, array $parameters): string {
        unset($parameters[0]);
        $replacement = implode(", ", $parameters);
        $replacement = str_replace("_", " ", $replacement);
        $replacement = Str::replaceLast(", ", " & ", $replacement);
        $replacement = Str::title($replacement);
        return str_replace(":fields", "$replacement", $message);
    }

    /**
     * 
     * @param string $attribute
     * @param mixed $value
     * @param array $parameters
     * @param Validator $validator
     * @return bool
     * @throws \Exception
     */
    public function validate(string $attribute, $value, array $parameters, Validator $validator): bool {
        $model = new $parameters[0];
        if (!$model instanceof Model) {
            throw new \Exception($parameters[0] . " is not an Eloquent model");
        }
        unset($parameters[0]);
        $this->fields = $parameters;

        $query = $model->query();
        $request = app("request");
        foreach($parameters as $parameter){
            $query->where($parameter, $request->get($parameter));
        }

        return $query->count() == 0;
    }

    /**
     * Custom error messages
     * 
     * @return array
     */
    public function getCustomErrorMessages(): array {
        return [
            $this->getName() => ":fields fields should be unique"
        ];
    }

}

'ANY_FIELD_CAN_CARRY_IT' => 'required|numeric|multiple_unique:'.YOUR_MODEL_HERE::class.',FIELD_1,FIELD_2,FIELD_3...',
+6

, - :

 'unique:table_name,column1,null,null,column2,'.$request->column2.',column3,check3'
0

Laravel where .

- :

 'firstName' => [
     Rule::unique('people', 'firstName')->where(function ($query) use ($lastName) {
         return $query->where('lastName', $lastName);
     })
 ],
0

Source: https://habr.com/ru/post/1545036/


All Articles