Есть ли способ ссылки на другое поле при указании существующего правила проверки в 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
,
Я надеюсь это имеет смысл.
Спасибо
Вы хотите пользовательское правило проверки, и я бы создал для этого отдельный класс. Но для краткости здесь почти то же самое с использованием встроенного замыкания:
// 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.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», а затем использую это поле в предложении «где».
Это очень удобно, потому что теперь мне больше не нужно настраиваемое правило проверки.
Поскольку ваши правила являются свойством модели, вам нужно внести в них некоторые изменения перед запуском валидатора.
Вы можете изменить свои правила на:
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']
);
в месте, где у вас есть набор данных.
попробуйте это работает для меня
'email'=>'required|unique:admintable,Email,'.$adminid.',admin_id',