Search code examples
phplaravelvalidationlaravel-formrequest

Laravel: Is it possible to apply different form validation rules to objects in an array


I have a Laravel 9 API.

I am posting the following json to an endpoint.

{
  "shapes": [
    {
      "type": "Point",
      "coordinates": [1, 2]
    },
    {
      "type": "MultiPolygon",
      "coordinates": [
        [
          [
            [1, 2],
            [3, 4],
            [5, 6],
          ]
        ]
      ]
    }
  ]
}

I have some form validation (in a form request class) that needs to validate the coordinates given differently based on the type.

I.e. Apply the PointCoordinatesValidator rule if the shape's type is Point or apply the MultiPolygonCoordinatesValidator rule if the shape's type is MultiPolygon.

public function rules()
{
    return [
        'shapes' => 'required|array|min:1',
        'shapes.*.type' => [
            'required',
            'string',
            'in:Point,MultiPolygon',
        ],
        'shapes.*.coordinates' => [
            'required',
            request()->input('shapes.*.type') == 'Point' ?
                new PointCoordinatesValidator :
                new MultiPolygonCoordinatesValidator,
        ],
    ];
}

However, when running this, the custom MultiPolygonCoordinatesValidator rule is being applied to both shapes, not just the shape where it's type == MultiPolygon.

I can see that request()->input('shapes.*.type') is Point for shapes.0 and MultiPolygon for shapes.1

Am I expecting too much from the validation? Is it possible to validate the different items in the array differently based on a value in that array?


Solution

  • Just pass the array element in and then implement the type check in your rule:

    'shapes.*' => [
                   'required',
                    new CoordinatesValidator(),
                  ],
    

    Then, in the rule, the $value will contain the type and the coordinates.