Skip to content

Make mappedBy fields optional on nested creates - #30

Closed
kac-axelor wants to merge 1 commit into
axelor:devfrom
kac-axelor:nested-create-mapped-by-fix
Closed

kac-axelor wants to merge 1 commit into
axelor:devfrom
kac-axelor:nested-create-mapped-by-fix

Conversation

@kac-axelor

@kac-axelor kac-axelor commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor

Creating a record nested under its parent no longer requires the mappedBy field the ORM fills in itself:

contact.create({
  data: { firstName: "a", lastName: "b", addresses: { create: [{ street: "1 Main" }] } }, // no `contact` needed
});

Previously the types demanded it, so callers passed a dummy contact: {} — every runtime test did. The schema generator now carries a collection's mappedBy key in the generated model types (addresses?: ToMany<Address, "contact">), and the create types make exactly that field optional in nested positions. Nothing else is relaxed: other required fields still error, and a direct address.create still requires contact, since there is no parent to fill it from.

The GraphQL schema mirrors the rule with per-relation input variants (AddressCreateWithoutContactInput) used by nested create/update inputs; direct mutation inputs keep the field NonNull. Making an input field nullable is backward-compatible for GraphQL clients.

Consumers pick this up by regenerating their client; clients generated with older versions keep the previous (stricter) behavior, since plain Relation<T>[] collections carry no mappedBy key.

Greens the two by-design failing cases in the type test suite (#27). Runtime tests drop the contact: {} workaround.


Series (merge order): #27 type tests (red by design) → #28 TypeScript 6.0 upgrade → #29 Options<> guard fix → #30 mappedBy fix. The suite in #27 goes fully green once all four are merged.

The ORM auto-fills a collection's mappedBy field from the parent
record, yet nested creates still demanded it, forcing callers to pass
dummy links like `contact: {}`.

Carry the schema's mappedBy key into the generated model types through
a branded collection type — ToMany<T, MappedBy> — emitted for OneToMany
fields, and relax exactly that field in nested CreateArgs. Mirror the
rule in the GraphQL schema with per-relation CreateWithout<Field>Input
variants, generated only when the target declares the field required.

Direct creates keep requiring the field: there is no parent to fill it
from. Runtime tests drop the now-unnecessary contact: {} workaround.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant