Skip to content

feat: nullable has-one returns null, add $hasOne for mutations#15

Closed
vparys wants to merge 1 commit intomainfrom
feat/nullable-has-one
Closed

feat: nullable has-one returns null, add $hasOne for mutations#15
vparys wants to merge 1 commit intomainfrom
feat/nullable-has-one

Conversation

@vparys
Copy link
Copy Markdown
Member

@vparys vparys commented Apr 10, 2026

Summary

  • Nullable has-one relations (author: Author | null) now return null from entity field access when disconnected, instead of always returning a HasOneAccessor with a placeholder entity
  • New entity.$hasOne('fieldName') method always returns HasOneAccessor regardless of connection state — for mutation access ($connect, $disconnect, $reset, etc.)
  • HasOneHandle.hasOne() delegation for nested $hasOne access (e.g. entity.author.$hasOne('avatar'))

API pattern

// Reading — null-safe with optional chaining
const authorName = article.author?.name.value ?? 'N/A'

// Mutations — always available via $hasOne
article.$hasOne('author').$connect('author-2')
article.$hasOne('author').$disconnect()

// Dirty state — via handle
const isDirty = article.$hasOne('author').$isDirty

Test plan

  • Typecheck passes (bun run typecheck)
  • All 21 has-one relation tests pass with updated patterns
  • Full test suite: 1376 pass, 0 new failures (9 pre-existing: 8 browser, 1 form has-many)

…r mutations

Nullable has-one relations (e.g. `author: Author | null`) now return `null`
from entity field access when the relation is disconnected, instead of always
returning a HasOneAccessor with a placeholder entity.

For mutation access (connect/disconnect), use `entity.$hasOne('fieldName')`
which always returns the HasOneAccessor regardless of connection state.
matej21 added a commit that referenced this pull request Apr 10, 2026
Alternative approach to #15. Instead of returning null for disconnected
nullable has-one relations, keep the placeholder entity pattern from
contember-oss binding. This provides a consistent API where has-one
always returns an accessor, and users check connection state via
$isConnected or $state.

Changes:
- Add $isConnected boolean getter to HasOneHandle and HasOneRefInterface
- Fix schema definitions to include nullable: true where entity types
  have | null (enables correct $remove() behavior: disconnect vs delete)
- Add placeholder behavior tests for nullable has-one relations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
matej21 added a commit that referenced this pull request Apr 10, 2026
Alternative approach to #15. Instead of returning null for disconnected
nullable has-one relations, keep the placeholder entity pattern from
contember-oss binding. This provides a consistent API where has-one
always returns an accessor, and users check connection state via
$isConnected or $state.

Changes:
- Add $isConnected boolean getter to HasOneHandle and HasOneRefInterface
- Fix schema definitions to include nullable: true where entity types
  have | null (enables correct $remove() behavior: disconnect vs delete)
- Add placeholder behavior tests for nullable has-one relations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vparys
Copy link
Copy Markdown
Member Author

vparys commented Apr 10, 2026

Fixed in #16.

@vparys vparys closed this Apr 10, 2026
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