diff --git a/src/entity/prelude.rs b/src/entity/prelude.rs index 447117b7..c0c0f5b5 100644 --- a/src/entity/prelude.rs +++ b/src/entity/prelude.rs @@ -1,9 +1,9 @@ pub use crate::{ error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity, - DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, Iden, IdenStatic, ModelTrait, - PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, - RelationTrait, Select, Value, + DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter, ForeignKeyAction, Iden, + IdenStatic, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, + RelationDef, RelationTrait, Select, Value, }; #[cfg(feature = "with-json")] diff --git a/src/entity/relation.rs b/src/entity/relation.rs index afc8aba1..6e90975a 100644 --- a/src/entity/relation.rs +++ b/src/entity/relation.rs @@ -9,6 +9,8 @@ pub enum RelationType { HasMany, } +pub type ForeignKeyAction = sea_query::ForeignKeyAction; + pub trait RelationTrait: Iterable + Debug + 'static { fn def(&self) -> RelationDef; } @@ -35,6 +37,8 @@ pub struct RelationDef { pub from_col: Identity, pub to_col: Identity, pub is_owner: bool, + pub on_delete: Option, + pub on_update: Option, } pub struct RelationBuilder @@ -49,6 +53,8 @@ where from_col: Option, to_col: Option, is_owner: bool, + on_delete: Option, + on_update: Option, } impl RelationDef { @@ -61,6 +67,8 @@ impl RelationDef { from_col: self.to_col, to_col: self.from_col, is_owner: !self.is_owner, + on_delete: self.on_delete, + on_update: self.on_update, } } } @@ -79,6 +87,8 @@ where from_col: None, to_col: None, is_owner, + on_delete: None, + on_update: None, } } @@ -91,6 +101,8 @@ where from_col: Some(rel.from_col), to_col: Some(rel.to_col), is_owner, + on_delete: None, + on_update: None, } } @@ -109,6 +121,16 @@ where self.to_col = Some(identifier.identity_of()); self } + + pub fn on_delete(mut self, action: ForeignKeyAction) -> Self { + self.on_delete = Some(action); + self + } + + pub fn on_update(mut self, action: ForeignKeyAction) -> Self { + self.on_update = Some(action); + self + } } impl From> for RelationDef @@ -124,6 +146,8 @@ where from_col: b.from_col.unwrap(), to_col: b.to_col.unwrap(), is_owner: b.is_owner, + on_delete: b.on_delete, + on_update: b.on_update, } } } diff --git a/src/entity/schema.rs b/src/entity/schema.rs index 930ce6aa..727eab06 100644 --- a/src/entity/schema.rs +++ b/src/entity/schema.rs @@ -89,6 +89,12 @@ where foreign_key_stmt.to_col(o3); } } + if let Some(action) = relation.on_delete { + foreign_key_stmt.on_delete(action); + } + if let Some(action) = relation.on_update { + foreign_key_stmt.on_update(action); + } stmt.foreign_key( foreign_key_stmt .name(&format!( diff --git a/tests/common/bakery_chain/baker.rs b/tests/common/bakery_chain/baker.rs index 0967fcf5..3dff66aa 100644 --- a/tests/common/bakery_chain/baker.rs +++ b/tests/common/bakery_chain/baker.rs @@ -60,6 +60,8 @@ impl RelationTrait for Relation { Self::Bakery => Entity::belongs_to(super::bakery::Entity) .from(Column::BakeryId) .to(super::bakery::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), } } diff --git a/tests/common/bakery_chain/cake.rs b/tests/common/bakery_chain/cake.rs index 3630d29a..8eaf8b9e 100644 --- a/tests/common/bakery_chain/cake.rs +++ b/tests/common/bakery_chain/cake.rs @@ -67,6 +67,8 @@ impl RelationTrait for Relation { Self::Bakery => Entity::belongs_to(super::bakery::Entity) .from(Column::BakeryId) .to(super::bakery::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), Self::Lineitem => Entity::has_many(super::lineitem::Entity).into(), } diff --git a/tests/common/bakery_chain/cakes_bakers.rs b/tests/common/bakery_chain/cakes_bakers.rs index 8106bbdf..e2067b59 100644 --- a/tests/common/bakery_chain/cakes_bakers.rs +++ b/tests/common/bakery_chain/cakes_bakers.rs @@ -56,10 +56,14 @@ impl RelationTrait for Relation { Self::Cake => Entity::belongs_to(super::cake::Entity) .from(Column::CakeId) .to(super::cake::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), Self::Baker => Entity::belongs_to(super::baker::Entity) .from(Column::BakerId) .to(super::baker::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), } } diff --git a/tests/common/bakery_chain/lineitem.rs b/tests/common/bakery_chain/lineitem.rs index 45a6037f..26ec828e 100644 --- a/tests/common/bakery_chain/lineitem.rs +++ b/tests/common/bakery_chain/lineitem.rs @@ -64,10 +64,14 @@ impl RelationTrait for Relation { Self::Order => Entity::belongs_to(super::order::Entity) .from(Column::OrderId) .to(super::order::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), Self::Cake => Entity::belongs_to(super::cake::Entity) .from(Column::CakeId) .to(super::cake::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), } } diff --git a/tests/common/bakery_chain/order.rs b/tests/common/bakery_chain/order.rs index 82b02dee..6fb8d212 100644 --- a/tests/common/bakery_chain/order.rs +++ b/tests/common/bakery_chain/order.rs @@ -65,10 +65,14 @@ impl RelationTrait for Relation { Self::Bakery => Entity::belongs_to(super::bakery::Entity) .from(Column::BakeryId) .to(super::bakery::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), Self::Customer => Entity::belongs_to(super::customer::Entity) .from(Column::CustomerId) .to(super::customer::Column::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) .into(), Self::Lineitem => Entity::has_many(super::lineitem::Entity).into(), } diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index 7e668f29..c9523572 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -68,8 +68,8 @@ pub async fn create_baker_table(db: &DbConn) -> Result { .name("fk-baker-bakery") .from(baker::Entity, baker::Column::BakeryId) .to(bakery::Entity, bakery::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .to_owned(); @@ -126,16 +126,16 @@ pub async fn create_order_table(db: &DbConn) -> Result { .name("fk-order-bakery") .from(order::Entity, order::Column::BakeryId) .to(bakery::Entity, bakery::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .foreign_key( ForeignKey::create() .name("fk-order-customer") .from(order::Entity, order::Column::CustomerId) .to(customer::Entity, customer::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .to_owned(); @@ -178,16 +178,16 @@ pub async fn create_lineitem_table(db: &DbConn) -> Result { .name("fk-lineitem-order") .from(lineitem::Entity, lineitem::Column::OrderId) .to(order::Entity, order::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .foreign_key( ForeignKey::create() .name("fk-lineitem-cake") .from(lineitem::Entity, lineitem::Column::CakeId) .to(cake::Entity, cake::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .to_owned(); @@ -219,16 +219,16 @@ pub async fn create_cakes_bakers_table(db: &DbConn) -> Result .name("fk-cakes_bakers-cake") .from(cakes_bakers::Entity, cakes_bakers::Column::CakeId) .to(cake::Entity, cake::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .foreign_key( ForeignKey::create() .name("fk-cakes_bakers-baker") .from(cakes_bakers::Entity, cakes_bakers::Column::BakerId) .to(baker::Entity, baker::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .to_owned(); @@ -258,8 +258,8 @@ pub async fn create_cake_table(db: &DbConn) -> Result { .name("fk-cake-bakery") .from(cake::Entity, cake::Column::BakeryId) .to(bakery::Entity, bakery::Column::Id) - // .on_delete(ForeignKeyAction::Cascade) - // .on_update(ForeignKeyAction::Cascade), + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), ) .col( ColumnDef::new(cake::Column::GlutenFree)