Laravel validation: exists with additional column condition - custom validation rule

匿名 (未验证) 提交于 2019-12-03 01:57:01

问题:

Is there is a way of referencing another field when specifying the exists validation rule in Laravel? I want to be able to say that input a must exist in table a, input b must exist in table b AND the value for column x in table b must equal input a.

Best explained by example:

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

So with my validation rules I want to be able to make sure that:

  • game_id exists within the games table (id field)
  • team1_id exists within the teams table (id field) and the game_id column (in the teams table) must equal the value of the game_id input.
  • As above for team2_id

So, if in my form, I entered 1 for game_id, I want to be able to ensure that the record within the teams table for both team1_id and team2_id have the value 1 for game_id.

I hope this makes sense.

Thanks

回答1:

You want a custom validation rule, and I would create a separate class for this. But for brevity here's pretty much the same using inline closure:

// 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) 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; }); 

Then use simply this:

$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:

EDIT: Supposedly this does not work in Laravel 5.5. @user3151197 answer might do the trick.

I'm using Laravel 5.4 and it has the ability to add a custom Rule to the exists and unique rules. I think this came into existence some time in 5.3

Here is my scenario: I have an email verifications table and I want to ensure that a passed machine code and activation code exist on the same row.

Be sure to include 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'                           ]; 

The first arguement in the exists method is the table and the second is the custom column name I'm using for the 'mc' field. I pass the second column I want to check using the 'use' keyword and then use that field in a a where clause.

This is pretty handy, because now I no longer need a custom Validation rule.



回答3:

As your rules are model property you need to make some change for them before running validator.

You could change your rules to:

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

and now you will need to use loop to insert correct value instead of {$game_id} string.

I can show you how I did it in my case for editing rule:

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; } 

You can do the same in your case changing {$game_id} into $data['game_id'] (in my case I changed {,id} into ,$editId

EDIT

Of course If you didn't have $rules set as property you could simply do:

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

in place where you have your data set.



回答4:

try this its works for me

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!