@@ -79,11 +79,13 @@ assert_eq!(
7979
8080## Self Referencing Relations
8181
82+ ### Belongs To
83+
8284``` rust title="staff.rs"
8385use sea_orm :: entity :: prelude :: * ;
8486
8587#[sea_orm:: model]
86- #[derive(Clone , Debug , PartialEq , DeriveEntityModel , Eq )]
88+ #[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
8789#[sea_orm(table_name = " staff" )]
8890pub struct Model {
8991 #[sea_orm(primary_key)]
@@ -93,37 +95,76 @@ pub struct Model {
9395 #[sea_orm(
9496 self_ref,
9597 relation_enum = " ReportsTo" ,
98+ relation_reverse = " Manages" ,
9699 from = " reports_to_id" ,
97100 to = " id"
98101 )]
99102 pub reports_to : HasOne <Entity >,
103+ #[sea_orm(self_ref, relation_enum = " Manages" , relation_reverse = " ReportsTo" )]
104+ pub manages : HasMany <Entity >,
100105}
101106
102107impl ActiveModelBehavior for ActiveModel {}
103108```
104109
105- ### Entity Loader
110+ (or using ` compact_model ` shim)
111+
112+ ``` rust title="staff.rs"
113+ use sea_orm :: entity :: prelude :: * ;
114+
115+ #[sea_orm:: compact_model]
116+ #[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
117+ #[sea_orm(table_name = " staff" )]
118+ pub struct Model {
119+ #[sea_orm(primary_key)]
120+ pub id : i32 ,
121+ pub name : String ,
122+ pub reports_to_id : Option <i32 >,
123+ #[sea_orm(self_ref, relation_enum = " ReportsTo" )]
124+ pub reports_to : HasOne <Entity >,
125+ #[sea_orm(self_ref, relation_enum = " Manages" )]
126+ pub manages : HasMany <Entity >,
127+ }
128+
129+ #[derive(Copy , Clone , Debug , EnumIter , DeriveRelation )]
130+ pub enum Relation {
131+ #[sea_orm(belongs_to = " Entity" , from = " Column::ReportsToId" , to = " Column::Id" )]
132+ ReportsTo ,
133+ #[sea_orm(has_many = " Entity" , via_rel = " Relation::ReportsTo" )]
134+ Manages ,
135+ }
136+
137+ impl ActiveModelBehavior for ActiveModel {}
138+ ```
139+
140+ #### Entity Loader
106141
107142``` rust
108- let staff = staff :: Entity :: load ()
109- . with (staff :: Relation :: ReportsTo )
143+ let staff = staff_compact :: Entity :: load ()
144+ . with (staff_compact :: Relation :: ReportsTo )
145+ . with (staff_compact :: Relation :: Manages )
110146 . all (db )
111147 . await ? ;
112148
113149assert_eq! (staff [0 ]. name, " Alan" );
114150assert_eq! (staff [0 ]. reports_to, None );
151+ assert_eq! (staff [0 ]. manages[0 ]. name, " Ben" );
152+ assert_eq! (staff [0 ]. manages[1 ]. name, " Alice" );
115153
116154assert_eq! (staff [1 ]. name, " Ben" );
117155assert_eq! (staff [1 ]. reports_to. as_ref (). unwrap (). name, " Alan" );
156+ assert! (staff [1 ]. manages. is_empty ());
118157
119158assert_eq! (staff [2 ]. name, " Alice" );
120- assert_eq! (staff [2 ]. reports_to. as_ref (). unwrap (). name, " Alan" );
159+ assert_eq! (staff [1 ]. reports_to. as_ref (). unwrap (). name, " Alan" );
160+ assert! (staff [2 ]. manages. is_empty ());
121161
122162assert_eq! (staff [3 ]. name, " Elle" );
123163assert_eq! (staff [3 ]. reports_to, None );
164+ assert! (staff [3 ]. manages. is_empty ());
124165```
125166
126- ### Model Loader
167+ #### Model Loader
127168
128169``` rust
129170let staff = staff :: Entity :: find ()
@@ -139,10 +180,10 @@ assert_eq!(staff[0].name, "Alan");
139180assert_eq! (reports_to [0 ], None );
140181
141182assert_eq! (staff [1 ]. name, " Ben" );
142- assert_eq! (reports_to [1 ]. unwrap (). name, " Alan" );
183+ assert_eq! (reports_to [1 ]. as_ref () . unwrap (). name, " Alan" );
143184
144185assert_eq! (staff [2 ]. name, " Alice" );
145- assert_eq! (reports_to [2 ]. unwrap (). name, " Alan" );
186+ assert_eq! (reports_to [2 ]. as_ref () . unwrap (). name, " Alan" );
146187
147188assert_eq! (staff [3 ]. name, " Elle" );
148189assert_eq! (reports_to [3 ], None );
@@ -152,11 +193,7 @@ It can work in reverse too.
152193
153194``` rust
154195let manages = staff
155- . load_self_rev (
156- staff :: Entity :: find (). order_by_asc (staff :: Column :: Id ),
157- staff :: Relation :: ReportsTo ,
158- db ,
159- )
196+ . load_self_many (staff :: Entity , staff :: Relation :: Manages , db )
160197 . await ? ;
161198
162199assert_eq! (staff [0 ]. name, " Alan" );
@@ -174,6 +211,102 @@ assert_eq!(staff[3].name, "Elle");
174211assert_eq! (manages [3 ]. len (), 0 );
175212```
176213
214+ ### Has Many (M-N)
215+
216+ ``` rust title="user.rs"
217+ #[sea_orm:: model]
218+ #[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
219+ #[sea_orm(table_name = " user" )]
220+ pub struct Model {
221+ #[sea_orm(primary_key)]
222+ pub id : i32 ,
223+ pub name : String ,
224+ #[sea_orm(self_ref, via = " user_follower" , from = " User" , to = " Follower" )]
225+ pub followers : HasMany <Entity >,
226+ #[sea_orm(self_ref, via = " user_follower" , reverse)]
227+ pub following : HasMany <Entity >,
228+ }
229+ ```
230+
231+ ``` rust title="user_follower.rs"
232+ #[sea_orm:: model]
233+ #[derive(Clone , Debug , PartialEq , DeriveEntityModel , Eq )]
234+ #[sea_orm(table_name = " user_follower" )]
235+ pub struct Model {
236+ #[sea_orm(primary_key)]
237+ pub user_id : i32 ,
238+ #[sea_orm(primary_key)]
239+ pub follower_id : i32 ,
240+ #[sea_orm(belongs_to, from = " user_id" , to = " id" )]
241+ pub user : Option <super :: user :: Entity >,
242+ #[sea_orm(belongs_to, relation_enum = " Follower" , from = " follower_id" , to = " id" )]
243+ pub follower : Option <super :: user :: Entity >,
244+ }
245+ ```
246+
247+ (or with ` compact_model ` )
248+
249+ ``` rust
250+ #[sea_orm:: compact_model]
251+ #[derive(Clone , Debug , PartialEq , Eq , DeriveEntityModel )]
252+ #[sea_orm(table_name = " user" )]
253+ pub struct Model {
254+ #[sea_orm(primary_key)]
255+ pub id : i32 ,
256+ pub name : String ,
257+ #[sea_orm(self_ref, via = " user_follower" )]
258+ pub followers : HasMany <Entity >,
259+ #[sea_orm(self_ref, via = " user_follower" , reverse)]
260+ pub following : HasMany <Entity >,
261+ }
262+
263+ impl RelatedSelfVia <super :: user_follower :: Entity > for Entity {
264+ fn to () -> RelationDef {
265+ super :: user_follower :: Relation :: Follower . def ()
266+ }
267+ fn via () -> RelationDef {
268+ super :: user_follower :: Relation :: User . def (). rev ()
269+ }
270+ }
271+ ```
272+
273+ #### Entity Loader
274+
275+ Join paths:
276+
277+ ``` rust
278+ user -> profile
279+ -> user_follower -> user -> profile
280+ -> user_follower (reverse ) -> user -> profile
281+ ```
282+
283+ ``` rust
284+ let users = user :: Entity :: load ()
285+ . with (profile :: Entity )
286+ . with ((user_follower :: Entity , profile :: Entity ))
287+ . with ((user_follower :: Entity :: REVERSE , profile :: Entity ))
288+ . all (db )
289+ . await ? ;
290+
291+ assert_eq! (users [1 ]. profile, bob . profile);
292+ assert_eq! (users [1 ]. followers. len (), 1 );
293+ assert_eq! (users [1 ]. followers[0 ], sam );
294+ assert_eq! (users [1 ]. following. len (), 1 );
295+ assert_eq! (users [1 ]. following[0 ], alice );
296+ ```
297+
298+ #### Model Loader
299+
300+ ``` rust
301+ let users = user :: Entity :: find (). all (db ). await ? ;
302+ let followers = users . load_self_via (user_follower :: Entity , db ). await ? ;
303+ let following = users . load_self_via_rev (user_follower :: Entity , db ). await ? ;
304+
305+ assert_eq! (users [1 ], bob );
306+ assert_eq! (followers [1 ], [sam . clone ()]);
307+ assert_eq! (following [1 ], [alice . clone ()]);
308+ ```
309+
177310## Diamond Relations
178311
179312Sometimes there exist multiple relations between a pair of entities. Here we take the simplest example, where ` Bakery ` can have multiple ` Worker ` .
0 commit comments