@@ -79,84 +79,158 @@ assert_eq!(
7979
8080## Self Referencing Relations
8181
82- The ` Link ` trait can also define self referencing relations. The following example defines an Entity that references itself.
83-
84- ``` rust title="self_join.rs"
82+ ``` rust title="staff.rs"
8583use sea_orm :: entity :: prelude :: * ;
8684
8785#[sea_orm:: model]
88- #[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
89- #[sea_orm(table_name = " self_join " )]
86+ #[derive(Clone , Debug , PartialEq , DeriveEntityModel , Eq )]
87+ #[sea_orm(table_name = " staff " )]
9088pub struct Model {
91- #[sea_orm(primary_key, auto_increment = false)]
92- pub uuid : Uuid ,
93- pub uuid_ref : Option <Uuid >,
94- pub time : Option <Time >,
95- #[sea_orm(self_ref, relation_enum = " SelfRef" , from = " uuid_ref" , to = " uuid" )]
96- pub other : HasOne <Entity >,
89+ #[sea_orm(primary_key)]
90+ pub id : i32 ,
91+ pub name : String ,
92+ pub reports_to_id : Option <i32 >,
93+ #[sea_orm(
94+ self_ref,
95+ relation_enum = " ReportsTo" ,
96+ from = " reports_to_id" ,
97+ to = " id"
98+ )]
99+ pub reports_to : HasOne <Entity >,
97100}
98101
99- pub struct SelfReferencingLink ;
102+ impl ActiveModelBehavior for ActiveModel {}
103+ ```
100104
101- impl Linked for SelfReferencingLink {
102- type FromEntity = Entity ;
103- type ToEntity = Entity ;
105+ ### Entity Loader
104106
105- fn link (& self ) -> Vec <RelationDef > {
106- vec! [Relation :: SelfRef . def ()] // <- use the relation here
107- }
108- }
107+ ``` rust
108+ let staff = staff :: Entity :: load ()
109+ . with (staff :: Relation :: ReportsTo )
110+ . all (db )
111+ . await ? ;
109112
110- impl ActiveModelBehavior for ActiveModel {}
113+ assert_eq! (staff [0 ]. name, " Alan" );
114+ assert_eq! (staff [0 ]. reports_to, None );
115+
116+ assert_eq! (staff [1 ]. name, " Ben" );
117+ assert_eq! (staff [1 ]. reports_to. as_ref (). unwrap (). name, " Alan" );
118+
119+ assert_eq! (staff [2 ]. name, " Alice" );
120+ assert_eq! (staff [2 ]. reports_to. as_ref (). unwrap (). name, " Alan" );
121+
122+ assert_eq! (staff [3 ]. name, " Elle" );
123+ assert_eq! (staff [3 ]. reports_to, None );
111124```
112125
113- ### Querying model pairs
126+ ### Model Loader
114127
115128``` rust
116- let models : Vec <(self_join :: Model , Option <self_join :: Model >)> = self_join :: Entity :: find ()
117- . find_also_linked (self_join :: SelfReferencingLink )
118- . order_by_asc (self_join :: Column :: Time )
129+ let staff = staff :: Entity :: find ()
130+ . order_by_asc (staff :: Column :: Id )
119131 . all (db )
120132 . await ? ;
133+
134+ let reports_to = staff
135+ . load_self (staff :: Entity , staff :: Relation :: ReportsTo , db )
136+ . await ? ;
137+
138+ assert_eq! (staff [0 ]. name, " Alan" );
139+ assert_eq! (reports_to [0 ], None );
140+
141+ assert_eq! (staff [1 ]. name, " Ben" );
142+ assert_eq! (reports_to [1 ]. unwrap (). name, " Alan" );
143+
144+ assert_eq! (staff [2 ]. name, " Alice" );
145+ assert_eq! (reports_to [2 ]. unwrap (). name, " Alan" );
146+
147+ assert_eq! (staff [3 ]. name, " Elle" );
148+ assert_eq! (reports_to [3 ], None );
149+ ```
150+
151+ It can works in reverse too.
152+
153+ ``` rust
154+ let manages = staff
155+ . load_self_rev (
156+ staff :: Entity :: find (). order_by_asc (staff :: Column :: Id ),
157+ staff :: Relation :: ReportsTo ,
158+ db ,
159+ )
160+ . await ? ;
161+
162+ assert_eq! (staff [0 ]. name, " Alan" );
163+ assert_eq! (manages [0 ]. len (), 2 );
164+ assert_eq! (manages [0 ][0 ]. name, " Ben" );
165+ assert_eq! (manages [0 ][1 ]. name, " Alice" );
166+
167+ assert_eq! (staff [1 ]. name, " Ben" );
168+ assert_eq! (manages [1 ]. len (), 0 );
169+
170+ assert_eq! (staff [2 ]. name, " Alice" );
171+ assert_eq! (manages [2 ]. len (), 0 );
172+
173+ assert_eq! (staff [3 ]. name, " Elle" );
174+ assert_eq! (manages [3 ]. len (), 0 );
121175```
122176
123177## Diamond Relations
124178
125- Sometimes there exist multiple relations between a pair of entities. Here we take the simplest example, where ` Cake ` can have multiple ` Fruit ` .
179+ Sometimes there exist multiple relations between a pair of entities. Here we take the simplest example, where ` Bakery ` can have multiple ` Worker ` .
126180
127181``` rust
128182#[sea_orm:: model]
129- #[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
130- #[sea_orm(table_name = " cake " )]
183+ #[derive(Clone , Debug , PartialEq , DeriveEntityModel )]
184+ #[sea_orm(table_name = " bakery " )]
131185pub struct Model {
132186 #[sea_orm(primary_key)]
133187 pub id : i32 ,
134188 pub name : String ,
135- pub topping_id : i32 ,
136- pub filling_id : i32 ,
137- #[sea_orm(belongs_to, relation_enum = " Topping " , from = " topping_id " , to = " id" )]
138- pub topping : HasOne <super :: fruit :: Entity >,
139- #[sea_orm(belongs_to, relation_enum = " Filling " , from = " filling_id " , to = " id" )]
140- pub filling : HasOne <super :: fruit :: Entity >,
189+ pub manager_id : i32 ,
190+ pub cashier_id : i32 ,
191+ #[sea_orm(belongs_to, relation_enum = " Manager " , from = " manager_id " , to = " id" )]
192+ pub manager : HasOne <super :: worker :: Entity >,
193+ #[sea_orm(belongs_to, relation_enum = " Cashier " , from = " cashier_id " , to = " id" )]
194+ pub cashier : HasOne <super :: worker :: Entity >,
141195}
142196```
143197
144- How can we define the ` Fruit ` Entity?
198+ How can we define the ` Worker ` Entity?
145199By default, ` has_many ` invokes the ` Related ` trait to define the relation.
146200As a consequence, we have to specify the ` Relation ` variant of the related entity manually with the ` via_rel ` attribute.
147201
148- ``` rust
202+ ``` rust title="worker.rs"
149203#[sea_orm:: model]
150204#[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
151- #[sea_orm(table_name = " fruit " )]
205+ #[sea_orm(table_name = " worker " )]
152206pub struct Model {
153207 #[sea_orm(primary_key)]
154208 pub id : i32 ,
155209 pub name : String ,
156- #[sea_orm(has_many, relation_enum = " ToppingOf" , via_rel = " Topping" )]
157- pub topping_of : HasMany <super :: cake :: Entity >,
158- #[sea_orm(has_many, relation_enum = " FillingOf" , via_rel = " Filling" )]
159- pub filling_of : HasMany <super :: cake :: Entity >,
210+ #[sea_orm(has_many, relation_enum = " BakeryManager" , via_rel = " Manager" )]
211+ pub manager_of : HasMany <super :: bakery :: Entity >,
212+ #[sea_orm(has_many, relation_enum = " BakeryCashier" , via_rel = " Cashier" )]
213+ pub cashier_of : HasMany <super :: bakery :: Entity >,
214+ }
215+ ```
216+
217+ For compact Entities, it looks like this:
218+
219+ ``` rust title="worker.rs"
220+ #[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
221+ #[sea_orm(table_name = " worker" )]
222+ pub struct Model {
223+ #[sea_orm(primary_key)]
224+ pub id : i32 ,
225+ pub name : String ,
226+ }
227+
228+ #[derive(Copy , Clone , Debug , EnumIter , DeriveRelation )]
229+ pub enum Relation {
230+ #[sea_orm(has_many = " super::bakery::Entity" , via_rel = " Relation::Manager" )]
231+ BakeryManager ,
232+ #[sea_orm(has_many = " super::bakery::Entity" , via_rel = " Relation::Cashier" )]
233+ BakeryCashier ,
160234}
161235```
162236
0 commit comments