## 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<E>` / `BelongsTo<Option<E>>` 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<E>` — 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<Option<E>>` — 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<Entity>` requires every `from` column to be `NOT NULL`, and
`BelongsTo<Option<Entity>>` 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<super::user::Entity>,          // required

#[sea_orm(belongs_to, from = "bakery_id", to = "id")]
pub bakery: BelongsTo<Option<super::bakery::Entity>>, // 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<Entity>` 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<Enum>` fields.

### Compatibility Notes

- `belongs_to` relations may now be typed `BelongsTo<Entity>` /
  `BelongsTo<Option<Entity>>`. 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<Entity>` (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<Option<..>>` impls, so compare an empty relation with
  `is_unloaded_or_not_found()` / `is_not_found()` / `as_ref()` rather than `== None`
  / `== Some(..)`.
