Laravel иногда проверяет на массивах - PullRequest
0 голосов
/ 30 ноября 2018

Предположим, у нас есть следующие данные формы:

{age: 15, father: "John Doe"}

Мы хотим иметь некоторую сложную логику для проверки поля father на основе других данных для того же элемента (в этом примере мы хотимподтвердите, что у отца по крайней мере 5 символов, когда ему <18 лет. </p>

Это можно сделать так:

Standard validation rules: ['age': 'required|integer']

$validator->sometimes('father', 'required|min:5', function($data) {
    return $data['age'] < 18;
});

Теперь мы хотим, чтобы со списком было то же самоепредметов.Итак, теперь у нас есть следующие данные формы:

[
  {age: 25, },
  {age: 15, father: "John Doe"},
  {age: 40, },
]

Общее правило проверки теперь выглядит так:

['items.*.age': 'required|integer']

Теперь моя задача - легко выразить правило sometimes для каждогополе father элемента, которое будет зависеть от поля age элемента.

$validator->sometimes('items.*.father', 'required|min:5', function($data) {
    // Does not work anymore: return $data['age'] < 18;
    // Any way to know which item we are dealing with here?
});

Один из способов, который я могу придумать, - это циклическое переключение элементов в обратном вызове валидатора after.Но это не выглядит очень элегантно: (

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Самый короткий подход, который я мог бы получить к работе, таков:

"items" => "required|array",
"items.*.age" => "required|integer",
"items.*.father" => "required_if:object.*.age,".implode(",",range(0,18))."|min:5"

Когда бы ни понадобился отец для этого человека, он должен иметь как минимум 5 символов.Отец нужен, когда возраст человека меньше 18 лет.

required_if работает с несколькими уравнениями, разделенными запятыми.Поэтому я написал 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 как implode(',',range(0,18)), чтобы получить эту часть.

Используемая мной тестовая установка:

Контроллер (используется HomeController)

function posttest(Request $request) {
    $validator = Validator::make($request->all(), [
        "object" => "required|array",
        "object.*.age" => "required|integer",
        "object.*.father" => "required_if:object.*.age,".implode(",",range(0,18))."|min:5"
    ]);

    if($validator->fails()){
        dd($validator->errors());
    }
}

Просмотр (тест.blade.php)

@extends('layouts.app')
@section('content')
<form action="{{URL::to("/posttest")}}" method="POST">
@csrf
<input type="number" name="object[0][age]" value="12">
<input type="text" name="object[0][father]" value="John">
<input type="number" name="object[1][age]" value="15">
<input type="text" name="object[1][father]" value="John Doe">
<input type="number" name="object[2][age]" value="17">
<input type="submit" value="gönder">
</form>
@endsection

Маршруты

Route::view("/test", "test");
Route::post('/posttest', "HomeController@posttest");
0 голосов
/ 17 декабря 2018

Не удалось заставить sometimes() работать так, как вам нужно.sometimes() не «зацикливает» элементы массива, его вызывают один раз.

Я предложил альтернативный подход, который не идеален, но, возможно, вы найдете его полезным.

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
    Validator::extend('father_required_if_child', function ($attribute, $value, $parameters, $validator) {

        $childValidator = Validator::make($value, [
            'age' => 'required|integer'
        ]);

        $childValidator->sometimes('father', 'required|min:5', function($data) {
            return is_numeric($data['age']) && $data['age'] < 18;
        });

        if (!$childValidator->passes()) {
            return false;
        }

        return true;

        // Issue: since we are returning a single boolean for three/four validation rules, the error message might
        // be too generic.

        // We could also ditch $childValidator and use basic PHP logic instead.
    });

    return [
        'items.*' => 'father_required_if_child'
    ];
}

Любопытно узнать, как это можно улучшить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...