Skip to content

feat: guard loaded entity keys from mutation - #349

Merged
elpete merged 2 commits into
nextfrom
issue/43
Aug 28, 2026
Merged

elpete merged 2 commits into
nextfrom
issue/43

Conversation

@elpete

@elpete elpete commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Closes #43

Issue review

Fit score: 8/10. A loaded entity’s primary key is its identity and is used to target writes and relationships. Letting it drift currently produces a particularly dangerous silent result: the save targets the replacement key and may update no row.

Reasons for

  • turns silent no-op or wrong-row behavior into an actionable error
  • makes entity identity immutable after loading
  • handles all components of composite keys

Reasons against

  • applications intentionally changing natural primary keys must create a new entity or use a direct query
  • generated CFML setters cannot be intercepted at assignment time, so the guard runs when Quick synchronizes/persists the entity

Implementation

  • throws QuickPrimaryKeyMutationException when a loaded entity key differs from its original value
  • permits assigning the same key value
  • records original keys before Quick creates loaded relationship references from raw IDs

Reproduction

The new public-API regression failed before the fix: findOrFail( 1 ).setId( 2 ).save() did not throw and silently targeted the replacement key.

Validation

  • focused save and has-many coverage: 34 passed, 0 failed, 0 errors
  • full suite: 498 passed, 0 failed, 0 errors, 3 skipped
  • box run-script format
  • git diff --check
  • qb dependency: 14.0.0-beta.3

@elpete
elpete merged commit d087d36 into next Aug 28, 2026
1 check passed
@elpete
elpete deleted the issue/43 branch August 28, 2026 19:19
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