Introduce BelongsTo#3133
Open
tyt2y3 wants to merge 6 commits into
Open
Conversation
…)" This reverts commit f0121e0.
* Rename `Has*Model` to `ActiveHas*` * Support non-null HasOne * Fix E0034 ambiguity: unify HasOne::loaded / ActiveHasOne::set constructors The per-cardinality inherent impls each defined a same-named associated constructor (loaded / set), so the unqualified paths HasOne::loaded and ActiveHasOne::set were ambiguous (E0034) at every call site — the E: EntityTrait where-bound does not disambiguate associated-function path resolution. The crate's own tests and doctests failed to compile as a result. Define loaded / set once on the cardinality-generic impl, dispatching arg-wrapping through IntoHasOneLoaded / IntoActiveHasOneSet helper traits (one impl for the required E case, one for the optional Option<E> case). Bare model -> required, Option<model> -> optional, resolved unambiguously. Also fixes an entity_loader test that passed a bare model to a nullable relation (cake.bakery is HasOne<Option<..>>), which the ambiguity had masked. * Support nested writes for duplicate-target belongs_to; clear() no-op on unset FK Two fixes to nested-ActiveModel save behavior: 1. belongs_to relations that share a target entity with another relation used to silently generate no save/detach code (the action codegen was gated on the target entity being unique), so their nested writes were no-ops. They now always generate: a belongs_to with an explicit relation_enum, or a non-unique target, is keyed by its relation variant via `set_parent_key_for` / `clear_parent_key_for` (the default variant is inferred the same way the loader does); a unique target keeps the entity-keyed path. Fixes e.g. `user_follower` (two belongs_to to `user`). 2. `clear_<field>()` on a nullable belongs_to whose FK column was never set (a freshly-built ActiveModel) returned `DbErr::AttrNotSet`; it is now a no-op, since an unset nullable FK is already effectively clear. Adds `test_belongs_to_duplicate_target` and `test_clear_unset_belongs_to_is_noop`. * Revert now-redundant turbofish to bare HasOne::loaded / ActiveHasOne::set With the E0034 root-cause fix in place, the unqualified constructors resolve unambiguously, so the per-site `::<Option<E>>::` turbofish is no longer needed. Revert it in the doc example, lib test modules, into_active_model bodies, and the integration tests so users see the clean bare-call form. The macro-generated code keeps its explicit turbofish (internal, not user-facing). * Fix ActiveModelEx optional belongs_to clearing * Split HasOne and BelongsTo --------- Co-authored-by: Chris Tsang <chris.2y3@outlook.com>
`belongs_to` now accepts `HasOne<E>` (legacy) in addition to the recommended `BelongsTo<E>` / `BelongsTo<Option<E>>`, so entities written against the earlier API keep compiling. A `HasOne`-typed `belongs_to` generates the pre-`BelongsTo` `ActiveHasOne` write path — it sets this row's own foreign key on save, with relation-keyed disambiguation for duplicate targets (two `belongs_to` to the same entity). `BelongsTo` remains the recommended type. Also fix `action()` skipping the insert of a brand-new row that has no column explicitly `Set` (e.g. an auto-increment-only primary key), which left the generated key unset and failed the subsequent model conversion. A genuinely new row (no primary key set) now always inserts, while an unchanged row that already has a primary key is still left untouched.
`derive_model_tests` and `entity_loader_tests` referenced `HasOne` where the fixtures now declare `BelongsTo`, so they failed to compile once a database backend feature enabled the test bodies. Update the import and constructor to `BelongsTo`.
Add `blogger_legacy`, a mirror of the `blogger` fixtures whose `belongs_to` fields keep the legacy `HasOne<E>` type, and `belongs_to_legacy_tests` covering nested writes (has_one + belongs_to, including a brand-new nested parent), many-to-many through a junction, duplicate-target `belongs_to`, and the entity loader. Document the `BelongsTo` / `HasOne` split in the changelog.
Run `build-tools/make-sync.sh` to bring `sea-orm-sync` in line with `src/` and `tests/`: propagate the legacy `HasOne` belongs_to support and the new `blogger_legacy` / `belongs_to_legacy_tests`. This also resyncs runtime files that had drifted from `src` (e.g. `ActiveHasOne`/`ActiveHasMany`/`ActiveBelongsTo` derives, and an un-stripped `async fn` in the entity loader).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the
BelongsTorelation type from #3118 ontomaster, but makes it opt-in so existingbelongs_tocode keeps compiling:belongs_tonow accepts the recommendedBelongsTo<E>/BelongsTo<Option<E>>(compile-time cardinality, paired withActiveBelongsTo) or the legacyHasOne<E>field type. AHasOne-typedbelongs_togenerates the pre-BelongsToActiveHasOnewrite path — it sets this row's own foreign key on save, with relation-keyed disambiguation for duplicate targets (twobelongs_toto the same entity).action()skipping the insert of a brand-new row that has no column explicitlySet(e.g. an auto-increment-only primary key), which previously left the generated key unset.Backward compatibility
BelongsTois the recommended type forbelongs_to;HasOne<E>remains supported as a legacy field type. Existing entities, examples, and doctests are unaffected.Tests
blogger_legacyfixtures (aHasOne-belongs_to mirror ofblogger) +belongs_to_legacy_tests: nested writes (has_one + belongs_to, including a brand-new nested parent), many-to-many through a junction, duplicate-targetbelongs_to, and the entity loader — all exercising the legacyHasOnepath.sea-orm-sync(rusqlite) green.Notes
sea-orm-syncregenerated viabuild-tools/make-sync.sh; this also resyncs runtime files that had drifted fromsrc.HasOne/ActiveHasOneinternal reshape relative to rc.42; the backward-compatibility work here targetsbelongs_tospecifically.