使用2个字段的Laravel表单验证是唯一的

时间:2017-02-08 14:33:32

标签: php laravel-5

如何在2个字段中使用唯一的验证规则?

一个。该应用程序不应允许两个人使用相同的名字和姓氏。

允许用户仅填写名字或仅填写姓氏。因为用户可能只有其中一个。

湾但是,如果用户只输入名字(格伦),则表格中的其他人不应该具有相同的名字(名字='格伦',姓氏=空)。另一个'格伦史密斯'确定。

我尝试了以下规则。当两个字段(名字和姓氏)都不为空时,它很有用:

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

此规则在b上失败。当只有一个领域时。

任何提示?

5 个答案:

答案 0 :(得分:13)

内置的unique验证器不会真正支持您尝试做的事情。它的目的是确保单个有效在数据库中是唯一的,而不是两个值的组合。但是,您可以创建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;
});

然后,您可以使用以下命令访问此新规则:

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

您可能会发现您可能需要稍微调整一下数据库查询,因为它未经测试。

答案 1 :(得分:6)

这是对这个问题的广泛回答以及如何创建laravel自定义验证器,您可以简单地复制和粘贴,并尝试稍后理解: 第1步 :创建提供商 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步 :更新配置文件夹 config / app.php 中的app.php,将您创建的提供程序包含在提供程序数组中

App\Providers\CustomValidatorProvider::class,

第3步 :创建自定义验证器,在我的情况下,我创建了多个唯一字段验证器 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...',

答案 2 :(得分:0)

我认为您正在寻找类似的东西:

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

答案 3 :(得分:0)

Laravel现在允许您将where子句添加到the unique rule中。

在您的情况下,您可以执行以下操作:

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

答案 4 :(得分:0)

在我的情况下,这在控制器中可以正常工作:

$request->validate([
    'firstName' => 'required|min:3|max:255|unique:people,firstName,NULL,id,lastname,' . $request->input('lastname'),
], [
    'unique' => 'Some message for "unique" error',
]);