Используйте «отдельное» правило проверки Laravel, но игнорируйте некоторые записи массива, основанные на свойстве массива - PullRequest
0 голосов
/ 10 июля 2019

Я хочу проверить массив входных данных, используя запрос формы в Laravel. Массив выглядит так:

[
  'issues' =>
  [
     'type' => 'prio_1',
     'note' => 'This is some text'
  ],
  [
     'type' => 'prio_2',
     'note' => 'This is some other text'
  ]
  [
     'type' => 'prio_1',
     'note' => 'This is yet some other text',
     'deleted' => true
  ]
]

Я хочу проверить, что поле type в этом массиве равно distinct, принимая во внимание, что третья запись массива - deleted и, следовательно, его следует игнорировать для этого правила. Использование

["issues.*.type" => 'required|distinct']

конечно не работает, так как это правило не может быть параметризовано, чтобы игнорировать правило в случае, если свойство массива имеет определенное значение. Фильтрация ввода для исключения удаленных записей также не подходит, поскольку индекс, заменяющий * в ответе, должен совпадать с исходным индексом в запросе.

Есть ли способ расширить правило distinct (с помощью пользовательского валидатора), чтобы разрешить такого рода проверки? Или любой другой способ разрешить это?

1 Ответ

1 голос
/ 10 июля 2019

Вы можете использовать замыкание и коллекцию , чтобы проверить, есть ли дубликаты (исключая «удаленные» элементы):

public function rules()
{
    return [
        "issues.*.type" => [
            'required', function ($attr, $value, $fail) {
                $count = collect($this->input('issues'))
                    ->reject(function ($item) {
                        return isset($item['deleted']) && $item['deleted'];
                    })
                    ->filter(function ($item) use ($value) {
                        return $item['type'] === $value;
                    })
                    ->count();

                if ($count > 1) {
                    $fail(__('validation.distinct'));
                }
            },
        ],
    ];
}

Чтобы сделать вещи более эффективными, вы также можете просто посчитать значения до и просто проверить, является ли количество больше одного:

public function rules()
{
    $duplicateTypes = collect($this->input('issues'))
        ->reject(function ($item) {
            return isset($item['deleted']) && $item['deleted'];
        })
        ->groupBy('type')
        ->map->count();

    return [
        "issues.*.type" => [
            'required', function ($attr, $value, $fail) use($duplicateTypes) {
                if ($duplicateTypes[$value] > 1) {
                    $fail(__('validation.distinct'));
                }
            },
        ],
    ];
}

...