Skip to main content

SeaORM FAQ.02

ยท 2 min read
Chris Tsang

FAQ.02 Why the empty enum Relation {} is needed even if an Entity has no relations?โ€‹

Consider the following example Post Entity:

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "posts")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub title: String,
pub text: String,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

The two lines for defining Relation is quite unnecessary right?

To explain the problem, let's dive slightly deeper into the macro-expanded entity:

The DeriveRelation macro simply implements the RelationTrait:

impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
match self {
_ => unreachable!()
}
}
}

Which in turn is needed by EntityTrait as an associated type:

impl EntityTrait for Entity {
type Relation = Relation;
...
}

It would be ideal if, when the user does not specify this associated type, the library automatically fills in a stub to satisfy the type system?

Turns out, there is such a feature in Rust! It is an unstable feature called associated_type_defaults.

Basically, it allows trait definitions to specify a default associated type, allowing it to be elided:

// only compiles in nightly
trait EntityTrait {
type Relation: Relation = EmptyRelation;
}

Due to our commitment to stable Rust, this may not land in SeaORM very soon. When it is stabilized, do remind us to implement this feature to get rid of those two lines!