【问题标题】:Laravel validation: exists with additional column condition - custom validation ruleLaravel 验证:存在附加列条件 - 自定义验证规则
【发布时间】:2014-11-25 02:47:15
【问题描述】:

在 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 的团队表中的记录具有1 的值game_id.

我希望这是有道理的。

谢谢

【问题讨论】:

  • 我从 5.3 开始就一直在使用这种格式,它对我有用。我很确定它是有效的,尽管我没有在他们的文档中看到它。 $this->mymodel->create_rules['company_id'] = 'required|exists:companies,id,type_id,' 。 $id;这意味着 company_id 必须存在于自己的表中,并且 type_id 字段必须是 $id 的值。
  • @Jin 非常感谢你我已经测试了你的格式并且它也适用于我(Laravel 7)我认为你的评论比标记的答案要好得多

标签: php validation laravel laravel-4 laravel-validation


【解决方案1】:

检查NULL条件

'game_id' => 'required|exists:games,id,another_column,NULL',

您可以使用 (,) 列名称和值添加更多条件。

【讨论】:

    【解决方案2】:

    你可以尝试其他方法

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

    【讨论】:

      【解决方案3】:

      如果其他人仍在使用 Laravel 6 或更高版本找到更好的解决方案,您可以简单地添加带有“存在”规则的字段名称,就像这样。

      $rules = $request->validate([
         'game_id' => 'required|exists:games,id',
         'team1_id' => 'required|exists:teams,id',
         'team2_id' => 'required|exists:teams,id'
      ]);
      

      要检查“teams”表中是否存在 game_id,您可以使用 IN: 规则。

      类似的东西:

      $rules = $request->validate([
         'game_id' => 'required|exists:games,id',
         'team1_id' => 'required|exists:teams,id|in:games',
         'team2_id' => 'required|exists:teams,id|in:games',
      ]);
      

      我希望这会对某人有所帮助。

      【讨论】:

        【解决方案4】:

        从 Laravel 5.3+ 开始,您可以将自定义 where 子句添加到 exists and unique rules

        这是我的场景:我有一个电子邮件验证表,我想确保传递的机器码和激活码存在于同一行。

        一定要use Illuminate\Validation\Rule;

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

        exists 方法中的第一个参数是表格,第二个参数是我用于“mc”字段的自定义列名。我通过了我想在 where 子句中检查的第二列。

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

        【讨论】:

        • @AaronHill,你在 laravel v5.5 中表现如何?
        • @roerjo 为什么你说它在 laravel 5.5 上不起作用?它在 laravel 7.x 中仍然有效。顺便说一句,你不需要闭包,你可以直接做 -&gt;where('activationCode', $activationCode)
        【解决方案5】:

        试试这个它对我有用

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

        【讨论】:

        • 如果管理员 id 来自请求,请不要使用它...这很容易受到变量注入的影响,并且有人可能会用一些管道和逗号欺骗您的验证.. 或者更糟糕的是甚至导致远程代码执行
        • 嘿@Tofandel 调用正则表达式,在调用验证之前只保留数字并删除其他字符用于 adminid ;)
        • 或者只是使用类似的东西..'email' =&gt; ['required', 'unique' =&gt; ['admintable', 'Email', $adminid, 'admin_id']]
        • 在 admin_id 来自请求的情况下,无论如何你都可能有一个验证器 'admin_id' =&gt; 'required|integer|exists:admins,id' 所以这个论点是没有实际意义的。
        【解决方案6】:

        你想要一个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'
        );
        

        【讨论】:

        • 这似乎工作得很好,谢谢。我将不得不阅读自定义验证规则。应该在哪里放置自定义验证类?干杯
        • 您的自定义代码可能有一些结构(或应该有),所以把它放在那里。在 Laravel 5 中,您将创建一个新的服务提供者,但是,这是不同的故事。
        【解决方案7】:

        由于您的规则是模型属性,因此您需要在运行验证器之前对其进行一些更改。

        您可以将规则更改为:

        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} 字符串。

        我可以向您展示我在编辑规则的案例中是如何做到的:

        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

        编辑

        当然,如果您没有将 $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']
        );
        

        在您拥有数据集的地方。

        【讨论】:

          猜你喜欢
          • 2017-04-11
          • 2018-02-18
          • 2014-04-22
          • 2019-02-12
          • 2016-11-22
          • 2017-12-01
          • 2018-03-02
          • 2020-05-25
          • 2018-04-18
          相关资源
          最近更新 更多