Nested ActiveModel Builder
Relevant source files
The following files were used as context for generating this wiki page:
The Nested ActiveModel Builder is a core feature of SeaORM 2.0 that allows developers to persist complex object graphs in a single operation. It provides a fluent, strongly-typed API to construct a model and its associated relations—including 1-1, 1-N, and M-N relationships—simultaneously. SeaORM automatically manages the dependency resolution, ensuring that records are inserted, updated, or deleted in the correct topological order to satisfy database foreign key constraints.
Sources: CLAUDE.md:73-77, src/lib.rs:271-275
This pattern significantly reduces the boilerplate code required to manage relational data manually. Instead of performing multiple sequential database calls and passing IDs between them, the builder allows for a declarative definition of the entire document tree which is then saved within a single transaction.
Sources: examples/quickstart/src/main.rs:252-255, sea-orm-sync/src/lib.rs:271-275
Builder Architecture and Workflow
The Nested ActiveModel Builder operates on ActiveModel types generated from entity definitions. In SeaORM 2.0, these entities use the #[sea_orm::model] attribute and define relations directly on the Model struct using specialized types like HasOne<T> and HasMany<T>.
Data Flow for Persistence
When a builder sequence is finalized with a .save(db) or .insert(db) call, SeaORM walks the entire document tree. It identifies which models are new, which are modified, and which associations need to be created (such as entries in junction tables for M-N relations).
The builder ensures that parent records are inserted before children when foreign keys require it, and junction tables are populated after both sides of a many-to-many relationship are established.
Sources: CLAUDE.md:80-101, examples/quickstart/src/main.rs:255-258
Relationship Handling
The builder provides specific methods for different types of relationships defined in the entity model.
1-1 and Belongs-To Relations
For 1-1 relationships (e.g., a User having one Profile), the builder provides set_ methods. SeaORM can figure out the dependency regardless of which side is defined first in the builder chain.
let bob = user::ActiveModel::builder()
.set_name("Bob")
.set_profile(profile::ActiveModel::builder().set_picture("Tennis"))
.insert(db)
.await?;
Sources: CLAUDE.md:80-85, examples/quickstart/src/main.rs:188-193
1-N and M-N Relations
For collections, the builder provides add_ methods or allows pushing to the ActiveModel fields directly. This is commonly used for posts belonging to a user or tags associated with a post.
| Method | Relationship Type | Description |
|---|---|---|
set_<relation> | 1:1 or Belongs-To | Sets a single related ActiveModel. |
add_<relation> | 1:N or M:N | Appends a related ActiveModel to the collection. |
push | 1:N or M:N | Used on existing ActiveModel fields to add children. |
replace_all | 1:N or M:N | Replaces the entire collection, triggering deletions for removed items. |
Sources: CLAUDE.md:87-101, examples/quickstart/src/main.rs:326-335
Dependency Resolution Logic
A critical feature of the Nested ActiveModel Builder is its ability to resolve topological dependencies. This is particularly useful in self-referential or complex circular-looking relationships.
SeaORM handles the ID propagation automatically. When a parent record is saved and receives a database-generated ID, that ID is automatically injected into the foreign key fields of all nested child models before they are persisted.
Sources: examples/quickstart/src/main.rs:248-258, sea-orm-sync/src/lib.rs:271-275
Implementation Example: Complex Graph
The following example demonstrates building a User with a Profile, multiple Posts, and Tags for those posts in a single fluent chain.
// CLAUDE.md:80-101, examples/quickstart/src/main.rs:188-210
let user = user::ActiveModel::builder()
.set_name("Bob")
.set_email("bob@sea-ql.org")
.set_profile(profile::ActiveModel::builder().set_picture("image.jpg"))
.add_post(
post::ActiveModel::builder()
.set_title("Nice weather")
.add_tag(tag::ActiveModel::builder().set_tag("sunny")),
)
.save(db)
.await?;
Advanced Operations
The builder also supports modifying existing graphs. By calling .into_active_model() on a loaded model, you can access the builder-like API to append new records or modify existing ones within the nested structure.
| Operation | Implementation Pattern |
|---|---|
| Append | model.posts.push(new_post_builder) |
| Update | model.profile.as_mut().set_picture("New") |
| Junctions | post.add_tag(existing_tag_model) |
Sources: CLAUDE.md:87-92, examples/quickstart/src/main.rs:223-231
Conclusion
The Nested ActiveModel Builder is a fundamental improvement in SeaORM 2.0, shifting the responsibility of relational integrity and transaction management from the developer to the ORM engine. By leveraging a fluent builder API and automated dependency resolution, it ensures that complex, multi-entity persistence operations remain type-safe, concise, and efficient.
Sources: src/lib.rs:271-275, sea-orm-sync/src/lib.rs:271-275