Skip to content

Add ActiveBelongsToNotNull + nullable belongs_to detach#3113

Open
tyt2y3 wants to merge 1 commit into
masterfrom
feat/active-has-one-rename
Open

Add ActiveBelongsToNotNull + nullable belongs_to detach#3113
tyt2y3 wants to merge 1 commit into
masterfrom
feat/active-has-one-rename

Conversation

@tyt2y3

@tyt2y3 tyt2y3 commented Jul 3, 2026

Copy link
Copy Markdown
Member

Follow-up to #3110.

  1. Rename (026dfe1e) — mechanical, word-boundary rename crate-wide:

    • HasOneModel -> ActiveHasOne
    • HasManyModel -> ActiveHasMany

    These are the active/write-side companions to HasOne/HasMany; the old *Model names read as loaded models. No behavior change.

  2. ActiveBelongsToNotNull + nullable detach (af16e86f):

    • New type ActiveBelongsToNotNull<E> with variants NotSet / Setno Delete. It is the active-side type for a non-nullable belongs_to, so trying to detach a relation whose self-FK cannot be nulled is now a compile error instead of a silent no-op / raw SQL constraint error at runtime.
    • The derive macro inspects each belongs_to's self-FK column nullability:
      • non-nullable FK -> field typed ActiveBelongsToNotNull (no delete_* / set_*_option builders generated)
      • nullable FK -> field typed ActiveHasOne, and Delete now detaches by setting the self-FK to NULL (previously a no-op)
    • from is snake_cased before lookup, so both a Column name (BakeryId) and a field name (user_id) resolve to the FK field. Composite / unresolvable from values fall back to ActiveHasOne with no detach (keeps them compiling).

Previously, calling delete/detach on a non-nullable belongs_to silently did nothing (or surfaced a raw DB constraint error). This makes the invariant type-level for belongs_to — the only relation whose FK nullability is visible to the derive macro — while keeping codegen concrete per field so downstream users don't need generic bounds.

@tyt2y3 tyt2y3 requested a review from Huliiiiii July 3, 2026 23:40
@tyt2y3 tyt2y3 force-pushed the feat/active-has-one-rename branch from af16e86 to d0b0735 Compare July 4, 2026 00:01
…elongs_to Delete now detaches

Introduce `ActiveBelongsToNotNull<E>` (variants: NotSet, Set) as the active-side
type for a non-nullable `belongs_to`. It has no `Delete` variant, so attempting
to detach a relation whose self-FK cannot be nulled is now a compile error rather
than a silent no-op or a raw SQL constraint error at runtime.

The derive macro inspects each `belongs_to` field's self-FK column:
- non-nullable FK -> field typed `ActiveBelongsToNotNull` (no delete_/set_option builders)
- nullable FK     -> field typed `ActiveHasOne`, and `Delete` now detaches by
                     setting the self-FK to NULL (previously a no-op)

`from` is snake_cased before lookup so both a Column name (`BakeryId`) and a field
name (`user_id`) resolve to the FK field. Composite or unresolvable `from` values
fall back to `ActiveHasOne` with no detach, keeping them compiling.

Adds `From<HasOne>`/`From<HasMany>` conversions for the active types and a
`test_belongs_to_nullable_detach` integration test.
@tyt2y3 tyt2y3 force-pushed the feat/active-has-one-rename branch from d0b0735 to b15f647 Compare July 4, 2026 10:05
@tyt2y3 tyt2y3 changed the title Rename Active{HasOne,HasMany}; add ActiveBelongsToNotNull + nullable belongs_to detach Add ActiveBelongsToNotNull + nullable belongs_to detach Jul 4, 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