0

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

8

Задача: Есть ли способ ссылаться на другое поле при задании правила валидации 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 ответ(ов)

0

Ваши правила являются свойствами модели, поэтому вам нужно внести некоторые изменения перед выполнением проверки валидатора.

Вы можете изменить свои правила на следующие:

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

в том месте, где у вас установлены данные.

0

Чтобы проверить условие 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. Это позволяет гибко настраивать условия валидации в зависимости от ваших требований.

0

В вашем коде вы задаете правила валидации для данных, связанных с играми и командами. Вы хотите обеспечить, чтобы 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 в другом формате.

Надеюсь, это поможет вам улучшить валидацию ваших данных!

0

Вы можете использовать следующий код, который работает для меня:

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

Этот пример валидации проверяет, что поле email обязательно (required) и уникально в таблице admintable, исключая запись с идентификатором администратора $adminid.

0

Если кто-то еще ищет лучшее решение для 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',
]);

Надеюсь, это поможет кому-то.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь