-
-
Notifications
You must be signed in to change notification settings - Fork 686
Open
Labels
Description
Discussed in #3020
Originally posted by thorsonlinguistics March 26, 2026
I'm trying to implement types that have a diamond relation. I've followed the documentation on diamond relations, but it doesn't seem to work as expected with the entity loader - the code compiles but the related fields are Unloaded on the ModelEx. A MWE is given below, following the quickstart example. The result is ModelEx { id: 1, name: "YumBakery", manager_id: 1, cashier_id: 2, manager: Unloaded, cashier: Unloaded }, but I'm expected manager and cashier to be loaded with the manager and cashier. Is there a different way I should be defining the attributes, or a different way I should be calling .with()?
use log::info;
mod bakery {
use sea_orm::entity::prelude::*;
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "bakery")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
pub manager_id: i32,
pub cashier_id: i32,
#[sea_orm(belongs_to, relation_enum = "Manager", from = "manager_id", to = "id")]
pub manager: HasOne<super::worker::Entity>,
#[sea_orm(belongs_to, relation_enum = "Cashier", from = "cashier_id", to = "id")]
pub cashier: HasOne<super::worker::Entity>,
}
impl ActiveModelBehavior for ActiveModel {}
}
mod worker {
use sea_orm::entity::prelude::*;
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "worker")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub name: String,
#[sea_orm(has_many, relation_enum = "BakeryManager", via_rel = "Manager")]
pub manager_of: HasMany<super::bakery::Entity>,
#[sea_orm(has_many, relation_enum = "BakeryCashier", via_rel = "Cashier")]
pub cashier_of: HasMany<super::bakery::Entity>,
}
impl ActiveModelBehavior for ActiveModel {}
}
#[tokio::main]
async fn main() -> Result<(), sea_orm::DbErr> {
///// Part 0: Setup Environment /////
// This disables sqlx's logging and enables sea-orm's logging with parameter injection,
// which is easier to debug.
let env = env_logger::Env::default().filter_or("RUST_LOG", "info,sea_orm=debug,sqlx=warn");
env_logger::Builder::from_env(env).init();
use sea_orm::{entity::*, query::*};
// Use a SQLite in memory database so no setup needed.
// SeaORM supports MySQL, Postgres, SQL Server as well.
let db = &sea_orm::Database::connect("sqlite::memory:").await?;
// Populate this fresh database with tables.
//
// All entities defined in this crate are automatically registered
// into the schema registry, regardless of which module they live in.
//
// The registry may also include entities from upstream crates,
// so here we restrict it to entities defined in this crate only.
//
// The order of entity definitions does not matter.
// SeaORM resolves foreign key dependencies automatically
// and creates the tables in the correct order with their keys.
db.get_schema_registry("seatest::*")
.sync(db)
.await?;
info!("Schema created.");
///// Part 1: CRUD with nested 1-1 and 1-N relations /////
info!("Create worker Bob");
let bob = worker::ActiveModel::builder()
.set_name("Bob")
.insert(db)
.await?;
info!("Create worker Alice");
let alice = worker::ActiveModel::builder()
.set_name("Alice")
.insert(db)
.await?;
info!("Create bakery with workers Alice and Bob");
let yum = bakery::ActiveModel::builder()
.set_name("YumBakery")
.set_manager_id(bob.id)
.set_cashier_id(alice.id)
.set_manager(worker::ActiveModel::builder().set_name("Bob"))
.set_cashier(worker::ActiveModel::builder().set_name("Alice"))
.insert(db)
.await?;
info!("Querying bakeries with workers");
let yum = bakery::Entity::load()
.filter_by_id(yum.id)
.with(bakery::Relation::Manager)
.with(bakery::Relation::Cashier)
.one(db)
.await?
.unwrap();
println!("{:?}", yum);
Ok(())
}
```</div>
Reactions are currently unavailable