Convalida di Laravel: esiste con condizioni di colonna aggiuntive – regola di validation personalizzata

C'è un modo di fare riferimento a un altro field quando si specifica la regola di validation esistente in Laravel? Voglio essere in grado di dire che l'input deve esistere nella tabella a, l'input b deve esistere nella tabella b AND il valore per la colonna x nella tabella b deve essere uguale a a.

Il meglio spiegato con l'esempio:

public $rules = arrays( '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>' ); 

Quindi, con le mie regole di validation, voglio essere in grado di assicurarmi che:

  • game_id esiste all'interno della tabella dei games (field id )
  • team1_id esiste all'interno della tabella delle teams (field id ) e la colonna game_id (nella tabella delle teams ) deve essere uguale al valore dell'ingresso game_id .
  • Come sopra per team2_id

Quindi, se nella mia forma, ho inserito 1 per game_id , voglio essere in grado di assicurarmi che il record all'interno della tabella delle squadre sia per team1_id che team2_id abbiano il valore 1 per game_id .

Spero che abbia senso.

Grazie

Vuoi una regola di validation personalizzata e vorrei creare una class separata per questo. Ma per brevità ecco praticamente la stessa cosa con la chiusura in linea:

 // 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] => arrays_get($input, $parameters[3])]; $count = $verifier->getMultiCount($collection, $column, (arrays) $value, $extra); return $count >= 1; }); 

Quindi usa semplicemente questo:

 $rules = arrays( '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' ); 

EDIT: Questo non funziona in Laravel 5.5. @ user3151197 risposta funziona per me in Laravel 5.5

Sto usando Laravel 5.4 e ha la possibilità di aggiungere una regola personalizzata alle regole esistenti e uniche. Penso che questo sia entrato in vigore da qualche tempo in 5.3

Ecco il mio scenario: ho una tabella di verifiche e-mail e voglio assicurarmi che sulla stessa row esista un codice macchina e un codice di triggerszione.

Assicurati di includere l' 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' ]; 

Il primo argomento nel metodo esiste è la tabella e il secondo è il nome della colonna personalizzata che sto usando per il field 'mc'. Passo la seconda colonna che voglio controllare usando la parola chiave 'use' e poi uso quel field nella clausola aa where.

Questo è abbastanza utile, perché ora non ho più bisogno di una regola di validation personalizzata.

Poiché le tue regole sono properties; del model, devi apportre delle modifiche prima di eseguire il validatore.

Puoi cambiare le tue regole per:

 public $rules = arrays( '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}' ); 

e ora dovrai usare il ciclo per inserire il valore corretto invece di {$game_id} string.

Posso mostrarti come ho fatto nel mio caso per la regola di modifica:

 public function validate($data, $translation, $editId = null) { $rules = $this->rules; $rules = arrays_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; } 

Puoi fare lo stesso nel tuo caso cambiando {$game_id} in $data['game_id'] (nel mio caso ho cambiato {,id} in ,$editId

MODIFICARE

Ovviamente se non avessi impostato $rules come properties; potresti semplicemente fare:

 $rules = arrays( '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'] ); 

sul posto where hai il tuo set di dati.

prova questo per me

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