Laravel валидация: проверка существования с условием по дополнительному столбцу - пользовательское правило валидации
Задача: Есть ли способ ссылаться на другое поле при задании правила валидации exists
в Laravel? Я хочу убедиться, что input a
существует в таблице a
, input b
существует в таблице b
, И значение для столбца x
в таблице b
должно равняться input a
.
Лучше всего это объяснить на примере:
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
существует в таблицеgames
(полеid
);team1_id
существует в таблицеteams
(полеid
), и столбецgame_id
(в таблицеteams
) должен равняться значениюgame_id
из ввода;- То же самое касается и
team2_id
.
Таким образом, если в форме я ввёл 1
для game_id
, я хочу убедиться, что записи в таблице teams
для обоих team1_id
и team2_id
имеют значение 1
для game_id
.
Надеюсь, это имеет смысл.
Спасибо!
5 ответ(ов)
Ваши правила являются свойствами модели, поэтому вам нужно внести некоторые изменения перед выполнением проверки валидатора.
Вы можете изменить свои правила на следующие:
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']
);
в том месте, где у вас установлены данные.
Чтобы проверить условие NULL в Laravel при валидации, вы можете использовать правило exists
с дополнительным условием. Например, в вашем случае вы хотите проверить, что game_id
существует в таблице games
, и при этом значение в столбце another_column
должно быть NULL
.
Ваш код выглядит так:
'game_id' => 'required|exists:games,id,another_column,NULL',
Таким образом, использование NULL
в условии позволяет вам уточнить запрос на существование, добавляя дополнительные условия. Вы можете добавить больше условий, указав имя столбца и его значение, разделяя их запятыми. Например, если вы хотите уточнить, что значение в another_column
должно быть NULL
, а в yet_another_column
равно какому-то значению, вы можете сделать это следующим образом:
'game_id' => 'required|exists:games,id,another_column,NULL,yet_another_column,some_value',
Где some_value
— это значение, которое вы хотите проверить для yet_another_column
. Это позволяет гибко настраивать условия валидации в зависимости от ваших требований.
В вашем коде вы задаете правила валидации для данных, связанных с играми и командами. Вы хотите обеспечить, чтобы game_id
, team1_id
и team2_id
были обязательными и существовали в соответствующих таблицах. Однако стоит отметить, что ваши правила могут быть улучшены.
Вот пример, как вы можете это сделать:
public $rules = [
'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,
];
Дополнительно, если вы хотите упростить код и сделать его более читабельным, вы можете использовать метод route
для извлечения game_id
, если он передается через URL, или передав его через параметры:
public function rules(Request $request)
{
return [
'game_id' => 'required|exists:games,id',
'team1_id' => 'required|exists:teams,id,game_id,' . $request->get('game_id'),
'team2_id' => 'required|exists:teams,id,game_id,' . $request->get('game_id'),
];
}
Это также обеспечит лучшую гибкость в случае, если вам потребуется передать game_id
в другом формате.
Надеюсь, это поможет вам улучшить валидацию ваших данных!
Вы можете использовать следующий код, который работает для меня:
'email'=>'required|unique:admintable,Email,'.$adminid.',admin_id',
Этот пример валидации проверяет, что поле email
обязательно (required
) и уникально в таблице admintable
, исключая запись с идентификатором администратора $adminid
.
Если кто-то еще ищет лучшее решение для Laravel 6 или выше, вы можете просто добавить имя поля с правилом "exists", например, так:
$rules = $request->validate([
'game_id' => 'required|exists:games,id',
'team1_id' => 'required|exists:teams,id',
'team2_id' => 'required|exists:teams,id'
]);
Если вам нужно проверить, присутствует ли game_id
в таблице "teams", вы можете использовать правило 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',
]);
Надеюсь, это поможет кому-то.
Как вывести сырой SQL-запрос в виде строки из билдера запросов?
Как создать пользовательские вспомогательные функции в Laravel
Ошибка "Класс 'UserTableSeeder' не существует" - Laravel 5.0 [php artisan db:seed]
Форматирование часового пояса для даты Carbon
В Laravel, как получить список всех файлов в публичной папке?