Проверка Laravel: существует с дополнительным условием столбца — пользовательское правило проверки

Есть ли способ ссылки на другое поле при указании существующего правила проверки в Laravel? Я хочу иметь возможность сказать, что вход a должен существовать в таблице a, вход b должен существовать в таблице b, а значение для столбца x в таблице b должно равняться входу 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

Итак, если в моей форме, я вошел 1 за game_idЯ хочу убедиться, что запись в таблице команд для обоих team1_id а также team2_id иметь значение 1 за game_id,

Я надеюсь это имеет смысл.

Спасибо

10

Решение

Вы хотите пользовательское правило проверки, и я бы создал для этого отдельный класс. Но для краткости здесь почти то же самое с использованием встроенного замыкания:

// 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'
);
9

Другие решения

РЕДАКТИРОВАТЬ: предположительно, это не работает в Laravel 5.5. @ user3151197 ответ может помочь.

Я использую Laravel 5.4, и у него есть возможность добавить кастом правило к существующим и уникальным правилам. Я думаю, что это возникло некоторое время в 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'
];

Первым аргументом в методе exist является таблица, а вторым — имя настраиваемого столбца, которое я использую для поля ‘mc’. Я пропускаю второй столбец, который хочу проверить, используя ключевое слово «use», а затем использую это поле в предложении «где».

Это очень удобно, потому что теперь мне больше не нужно настраиваемое правило проверки.

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

в месте, где у вас есть набор данных.

2

попробуйте это работает для меня

'email'=>'required|unique:admintable,Email,'.$adminid.',admin_id',
1
По вопросам рекламы [email protected]