HeyJanny's avatar

Validating arrays of different objects

Hello, so basically i have a form stored in DB that is presented to frontend. Form contains many groups, think of it as a sort of groupped inputs. Each group has unique name in the scope of form and many fields. input has it's type and unique name in the scope of group, as we know we can have checkboxes selects or text/number inupts. I expect the front to send me the data as follows:

{
  "form": {
    "id": 17,
    "groups": [
      {
        "name": "account_name",
        "fields": [
          {
            "name": "account_name",
            "value": 1234
          }
        ]
      },
      {
        "name": "service",
        "fields": [
          {
            "name": "service",
            "value": "courier"
          }
        ]
      },
      {
        "name": "sizing",
        "fields": [
          {
            "name": "small",
            "value": 1
          }
        ]
      },
      {
        "name": "posh_services",
        "fields": [
          {
            "name": "super_fast",
            "value": true
          },
          {
            "name": "gilded_box",
            "value": true
          }
        ]
      }
    ]
  }
}

So here we have an example fo filled form sent from frontend. It has 4 different groups, each groups has filled fields. Is there any smooth and simple way to validate the:

  • field.value so they match type - for example true/false or 1/0 for checkbox, numerics for numeric inputs and so on?
  • field.name so Im sure the field actually exists/belongs for/to given group
  • group.name so Im sure the group exists/belongs for/to given form
0 likes
2 replies
tisuchi's avatar

@heyjanny How about this validation?

$validator = Validator::make($request->all(), [
    'form.id' => 'required|integer',
    'form.groups.*.name' => 'required|string',
    'form.groups.*.fields.*.name' => 'required|string',
    ...
]);

if ($validator->fails()) {
    // Validation failure
}
HeyJanny's avatar

@tisuchi im aware of similar validation and im using it right now. This seems too broad though. It doesnt validate if certain group belogs to given form nor the value of the field. The only solution that comes to my mind is that since i have the form.id i can validate it for existence then load its groups and fields of each group and wite some custom complicated validation logic that validates if data from frontend matches the relations, field types etc. It seems very dirty though. Maybe i did not include it in my post but the thing is i want to validate structure itself too, say the JSON in 1st post passes the validation but consider the following examples: example 1: group not related / field not related

{
  "form": {
    "id": 17,
    "groups": [
      {
        "name": "account_name",
        "fields": [
          {
            "name": "account_name",
            "value": 1234
          }
        ]
      },
      {
        "name": "service",
        "fields": [
          {
            "name": "service",
            "value": "courier"
          }
        ]
      },
      {
        "name": "sizing",
        "fields": [
          {
            "name": "small",
            "value": 1
          },
          {
            "name": "unrelated_field",
            "value": 1
          }
        ]
      },
      {
        "name": "posh_services",
        "fields": [
          {
            "name": "super_fast",
            "value": true
          },
          {
            "name": "gilded_box",
            "value": true
          }
        ]
      },
      {
        "name": "unrelated_group",
        "fields": [
          {
            "name": "abc",
            "value": "def"
          }
        ]
      }
    ]
  }
}

in this example i'd need to fail validation since theres one unrelated_group and one of the fields in group "sizing" has unrelated field. I need this to be validated against current state of form and it's relations in DB.

example 2: wrong type of value for field

{
  "form": {
    "id": 17,
    "groups": [
      {
        "name": "account_name",
        "fields": [
          {
            "name": "account_name",
            "value": 1234
          }
        ]
      },
      {
        "name": "service",
        "fields": [
          {
            "name": "service",
            "value": "courier"
          }
        ]
      },
      {
        "name": "sizing",
        "fields": [
          {
            "name": "small",
            "value": 1
          }
        ]
      },
      {
        "name": "posh_services",
        "fields": [
          {
            "name": "super_fast",
            "value": true
          },
          {
            "name": "gilded_box",
            "value": "maybe"
          }
        ]
      }
    ]
  }
}

in this example field with name "gilded_box" has wrong value type. Again I have got the info on field value type stored in DB but it all seems convoluted and i feel like im missing some easy way to achieve this kind of validation

Please or to participate in this conversation.