Skip to content

Faker: Respect required and nullable: false for nested object properties in arrays #114

@siggi-k

Description

@siggi-k

Faker: Respect required and nullable: false for nested object properties in arrays

Problem

For array properties whose items are objects (typically used for JSONB columns), the faker stub generator ignores the required list and the nullable: false flag on nested sub-properties. It always wraps each nested value with $faker->optional(0.92)->... and a ?? null fallback, even though the spec explicitly declares those sub-properties as required and non-nullable.

This causes the generated faker to produce null values in ~8% of cases per sub-property. Downstream model validators that reject null (e.g. via isset() checks or is_int() / is_numeric() type guards) then silently fail the save() call, leaving no record in the database.

The same required / nullable: false handling already works correctly for top-level model attributes — the bug is limited to sub-properties resolved through FakerStubResolver::fakeForObject() / resolveElement().

Expected Behavior

When the items schema of an array property declares a required list or nullable: false on its sub-properties, the generator should emit the bare faker call for those sub-properties — without optional(0.92) wrapping and without a ?? null fallback. This mirrors the existing behavior for top-level attributes.

Example

cashDiscounts:
  description: List of cash discounts for this payment method.
  type: array
  x-db-type: jsonb
  default: []
  items:
    type: object
    required:
      - days
      - percentage
    properties:
      days:
        type: integer
        nullable: false
      percentage:
        type: number
        nullable: false
        minimum: 0
        maximum: 100

Expected generated faker stub:

'cashDiscounts' => array_map(function () use ($faker, $uniqueFaker) {
    return [
        'days' => $faker->numberBetween(0, 1000000),
        'percentage' => $faker->randomFloat(null, 0, 100),
    ];
}, range(1, 4)),

Actual (broken) generated faker stub:

'cashDiscounts' => array_map(function () use ($faker, $uniqueFaker) {
    return [
        'days' => $faker->optional(0.92)->numberBetween(0, 1000000) ?? null,
        'percentage' => $faker->optional(0.92)->randomFloat(null, 0, 100) ?? null,
    ];
}, range(1, 4)),

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions