34

在 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

因此,如果在我的表单中,我输入1game_id,我希望能够确保团队表中的记录同时具有team1_idteam2_id1game_id

我希望这是有道理的。

谢谢

4

7 回答 7

40

从 Laravel 5.3+ 开始,您可以将自定义 where 子句添加到存在和唯一规则

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

务必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 子句中检查的第二列。

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

于 2017-06-15T18:06:42.297 回答
25

你想要一个自定义验证规则,我会为此创建一个单独的类。但为简洁起见,这里使用内联闭包几乎相同:

// 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'
);
于 2014-09-30T13:45:28.313 回答
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}字符串。

我可以向您展示我在编辑规则的情况下是如何做到的:

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']
);

在您拥有数据集的地方。

于 2014-09-30T13:23:00.527 回答
4

检查NULL 条件

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

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

于 2021-06-01T11:29:03.780 回答
2

试试这个它对我有用

'email'=>'required|unique:admintable,Email,'.$adminid.',admin_id',
于 2017-06-20T11:10:48.290 回答
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
);
于 2021-02-17T10:47:36.420 回答
0

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

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

并检查 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',
]);

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

于 2020-08-11T05:56:17.880 回答