## Release Notes: SeaORM 2.0.0-rc.43 *(since 2.0.0-rc.42)* ### New Features **`BelongsTo` relation type** (#3118, #3133, #3134) A dedicated `BelongsTo` / `BelongsTo>` type for `belongs_to` relations, alongside the existing `HasOne`. Cardinality lives in the type parameter, so the foreign-key nullability is expressed — and checked — at compile time: - `BelongsTo` — the FK is `NOT NULL`; the relation cannot be detached (there is no way to set it to "none" on the active side), so orphaning a required parent is a compile error rather than a runtime constraint violation. - `BelongsTo>` — the FK is nullable; the relation can be detached, which nulls the FK on save. The cardinality is validated against the FK columns when the entity is derived: `BelongsTo` requires every `from` column to be `NOT NULL`, and `BelongsTo>` requires at least one nullable `from` column — a mismatch is a compile error. Composite foreign keys with mixed nullability detach by nulling only their nullable columns. ```rust #[sea_orm(belongs_to, from = "user_id", to = "id")] pub author: BelongsTo, // required #[sea_orm(belongs_to, from = "bakery_id", to = "id")] pub bakery: BelongsTo>, // optional ``` The active side is `ActiveBelongsTo<..>`, mirroring `ActiveHasOne` / `ActiveHasMany`. **`HasOne` still works for `belongs_to` — no migration required** (#3133) Adopting `BelongsTo` is opt-in. A `belongs_to` field may keep its existing `HasOne` type; it continues to compile and behave as before. Use `BelongsTo` when you want the compile-time cardinality guarantee; otherwise nothing changes. ### Enhancements **CLI lists valid options on generation error** (#3131) `sea-orm-cli generate entity` now prints the valid choices when an invalid option value is supplied, instead of only reporting that the value was rejected. ### Bug Fixes **`has_related` with a `Condition::any()` filter** (#3126) `has_related` wrapped the caller's condition and then added the mandatory FK/join condition to it. When the caller passed a `Condition::any()` (an `OR` group), the join condition was folded into that disjunction, so the relation constraint was no longer guaranteed. The caller's condition is now wrapped in `Condition::all()` first, yielding `(caller condition) AND (fk join)` regardless of `any()` / `all()`. **Entity codegen for PostgreSQL enum array columns** (#3120) Array-of-enum columns were generated as scalar active-enum fields because the type resolver unwrapped `Array(Enum)` to `Enum`. Array columns now route through the full type resolver, so `enum[]` columns generate `Vec` fields. ### Compatibility Notes - `belongs_to` relations may now be typed `BelongsTo` / `BelongsTo>`. This is opt-in — existing `HasOne`-typed `belongs_to` fields are unchanged and still supported. `sea-orm-cli` continues to generate the `HasOne` form. - The compile-time detach guarantee applies only to `BelongsTo` (non-null); it is a property of the type, so it costs nothing at runtime. - A `BelongsTo` field's type parameter must match its FK nullability (checked when the entity is derived). This only affects code that opts into `BelongsTo`. - The nested-`ActiveModel` relation types remain semver-exempt (unstable): rc.43 drops their `PartialEq>` impls, so compare an empty relation with `is_unloaded_or_not_found()` / `is_not_found()` / `as_ref()` rather than `== None` / `== Some(..)`.