首页 文章

Laravel验证:存在附加列条件 - 自定义验证规则

提问于
浏览
9

在Laravel中指定存在的验证规则时,是否有一种引用另一个字段的方法?我希望能够说输入a必须存在于表a中,输入b必须存在于表b中,并且表b中列x的值必须等于输入a .

最好用例子解释:

public $rules = array(
    'game_id' => 'required|exists:games,id',
    'team1_id' => 'required|exists:teams,id,game_id,<game_id input value here>',
    'team2_id' => 'required|exists:teams,id,game_id,<game_id input value here>'
);

因此,根据我的验证规则,我希望能够确保:

  • game_id 存在于 games 表( id 字段)中

  • team1_id 存在于 teams 表( id 字段)中, game_id 列(在 teams 表中)必须等于 game_id 输入的值 .

  • 如上 team2_id

因此,如果在我的表单中,我为 game_id 输入 1 ,我希望能够确保 team1_idteam2_id 的团队表中的记录具有 game_id 的值 game_id .

我希望这是有道理的 .

谢谢

4 回答

  • 1

    你想要一个custom validation rule,我会为此创建一个单独的类 . 但为简洁起见,使用内联闭包几乎相同:

    // give it meaningful name, I'll go with game_fixture as an example
    Validator::extend('game_fixture', function ($attribute, $value, $parameters, $validator) 
    {
        if (count($parameters) < 4)
        {
            throw new \InvalidArgumentException("Validation rule game_fixture requires 4 parameters.");
        }
    
        $input    = $validator->getData();
        $verifier = $validator->getPresenceVerifier();
    
        $collection = $parameters[0];
        $column     = $parameters[1];
        $extra      = [$parameters[2] => array_get($input, $parameters[3])];
    
        $count = $verifier->getMultiCount($collection, $column, (array) $value, $extra);
    
        return $count >= 1;
    });
    

    然后使用这个:

    $rules = array(
        'game_id' => 'required|exists:games,id',
    
        // last parameter here refers to the 'game_id' value passed to the validator
        'team1_id' => 'required|game_fixture:teams,id,game_id,game_id',
        'team2_id' => 'required|game_fixture:teams,id,game_id,game_id'
    );
    
  • 2

    编辑:据说这在Laravel 5.5中不起作用 . @ user3151197回答可能会解决问题 .

    我正在使用Laravel 5.4,它能够将自定义Rule添加到存在且唯一的规则中 . 我认为这在5.3中出现了一段时间

    这是我的方案:我有一个电子邮件验证表,我想确保在同一行上存在传递的机器代码和激活码 .

    一定要包括 use Illuminate\Validation\Rule;

    $activationCode = $request->activation_code;                                   
    
    $rules = [                                                                     
        'mc' => [                                                                  
            'required',                                                            
            Rule::exists('email_verifications', 'machineCode')                     
            ->where(function ($query) use ($activationCode) {                      
                $query->where('activationCode', $activationCode);                  
            }),                                                                    
        ],                                                                         
        'activation_code' => 'required|integer|min:5',                             
        'operating_system' => 'required|alpha_num|max:45'                          
    ];
    

    exists方法中的第一个争论是表,第二个是我用于'mc'字段的自定义列名 . 我使用'use'关键字传递我要检查的第二列,然后在where子句中使用该字段 .

    这非常方便,因为现在我不再需要自定义验证规则 .

  • 11

    由于您的规则是模型属性,因此在运行验证程序之前需要对它们进行一些更改 .

    您可以将规则更改为:

    public $rules = array(
        'game_id' => 'required|exists:games,id',
        'team1_id' => 'required|exists:teams,id,game_id,{$game_id}',
        'team2_id' => 'required|exists:teams,id,game_id,{$game_id}'
    );
    

    现在你需要使用循环来插入正确的值而不是 {$game_id} string .

    我可以告诉你我在编写规则时如何做到这一点:

    public function validate($data, $translation, $editId = null)
    {
        $rules = $this->rules;
    
        $rules = array_intersect_key($rules, $data);
    
        foreach ($rules as $k => $v) {
            $rules[$k] = str_replace('{,id}',is_null($editId) ? '' : ','.$editId , $v);
        }
    
        $v = Validator::make($data, $rules, $translation);
    
        if ($v->fails())
        {
            $this->errors = $v->errors();
            return false;
        }
    
        return true;
    }
    

    您可以在将 {$game_id} 更改为 $data['game_id'] 的情况下执行相同操作(在我的情况下,我将 {,id} 更改为 ,$editId

    EDIT

    当然,如果您没有将 $rules 设置为属性,则可以执行以下操作:

    $rules = array(
        'game_id' => 'required|exists:games,id',
        'team1_id' => 'required|exists:teams,id,game_id,'.$data['game_id'],
        'team2_id' => 'required|exists:teams,id,game_id,'.$data['game_id']
    );
    

    在您拥有数据集的位置 .

  • 8

    试试这个适合我

    'email'=>'required|unique:admintable,Email,'.$adminid.',admin_id',
    

相关问题