Skip to content

Commit 587f9f0

Browse files
committed
[SeaORM] Edit
1 parent a600695 commit 587f9f0

File tree

4 files changed

+167
-93
lines changed

4 files changed

+167
-93
lines changed

SeaORM/docs/06-relation/01-one-to-one.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,16 @@ pub struct Model {
7676
<summary>It's expanded to:</summary>
7777

7878
```rust
79-
#[derive(Copy, Clone, Debug, EnumIter)]
79+
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
8080
pub enum Relation {
81+
#[sea_orm(
82+
belongs_to = "super::cake::Entity",
83+
from = "Column::CakeId",
84+
to = "super::cake::Column::Id"
85+
)]
8186
Cake,
8287
}
8388

84-
impl RelationTrait for Relation {
85-
fn def(&self) -> RelationDef {
86-
match self {
87-
Self::Cake => Entity::belongs_to(super::cake::Entity)
88-
.from(Column::CakeId)
89-
.to(super::cake::Column::Id)
90-
.into(),
91-
}
92-
}
93-
}
94-
9589
impl Related<super::cake::Entity> for Entity {
9690
fn to() -> RelationDef {
9791
Relation::Cake.def()

SeaORM/docs/06-relation/02-one-to-many.md

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl Related<super::fruit::Entity> for Entity {
3838

3939
## Defining the Inverse Relation
4040

41-
It is the same as defining the one-to-one inverse relation. The rule of thumb is, always define a `belongs_to` on the Entity with a foreign key `xxx_id`.
41+
It is the same as defining the one-to-one inverse relation, just without a unique key. The rule of thumb is, always define a `belongs_to` on the Entity with a foreign key `xxx_id`.
4242

4343
```rust {9,10} title="entity/fruit.rs"
4444
#[sea_orm::model]
@@ -58,22 +58,16 @@ pub struct Model {
5858
<summary>It's expanded to:</summary>
5959

6060
```rust
61-
#[derive(Copy, Clone, Debug, EnumIter)]
61+
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
6262
pub enum Relation {
63+
#[sea_orm(
64+
belongs_to = "super::cake::Entity",
65+
from = "Column::CakeId",
66+
to = "super::cake::Column::Id"
67+
)]
6368
Cake,
6469
}
6570

66-
impl RelationTrait for Relation {
67-
fn def(&self) -> RelationDef {
68-
match self {
69-
Self::Cake => Entity::belongs_to(super::cake::Entity)
70-
.from(Column::CakeId)
71-
.to(super::cake::Column::Id)
72-
.into(),
73-
}
74-
}
75-
}
76-
7771
impl Related<super::cake::Entity> for Entity {
7872
fn to() -> RelationDef {
7973
Relation::Cake.def()
@@ -86,32 +80,46 @@ impl Related<super::cake::Entity> for Entity {
8680

8781
Composite foreign key is supported using a tuple syntax.
8882

89-
```rust
90-
mod composite_a {
91-
#[sea_orm::model]
92-
#[sea_orm(table_name = "composite_a")]
93-
pub struct Model {
94-
#[sea_orm(primary_key)]
95-
pub id: i32,
96-
#[sea_orm(unique_key = "pair")]
97-
pub left_id: i32,
98-
#[sea_orm(unique_key = "pair")]
99-
pub right_id: i32,
100-
#[sea_orm(has_one)]
101-
pub b: Option<super::composite_b::Entity>,
102-
}
83+
```rust title="composite_a.rs"
84+
#[sea_orm::model]
85+
#[sea_orm(table_name = "composite_a")]
86+
pub struct Model {
87+
#[sea_orm(primary_key)]
88+
pub id: i32,
89+
#[sea_orm(unique_key = "pair")]
90+
pub left_id: i32,
91+
#[sea_orm(unique_key = "pair")]
92+
pub right_id: i32,
93+
#[sea_orm(has_one)]
94+
pub b: Option<super::composite_b::Entity>,
10395
}
96+
```
10497

105-
mod composite_b {
106-
#[sea_orm::model]
107-
#[sea_orm(table_name = "composite_b")]
108-
pub struct Model {
109-
#[sea_orm(primary_key)]
110-
pub id: i32,
111-
pub left_id: i32,
112-
pub right_id: i32,
113-
#[sea_orm(belongs_to, from = "(left_id, right_id)", to = "(left_id, right_id)")]
114-
pub a: Option<super::composite_a::Entity>,
115-
}
98+
```rust title="composite_b.rs"
99+
#[sea_orm::model]
100+
#[sea_orm(table_name = "composite_b")]
101+
pub struct Model {
102+
#[sea_orm(primary_key)]
103+
pub id: i32,
104+
pub left_id: i32,
105+
pub right_id: i32,
106+
#[sea_orm(belongs_to, from = "(left_id, right_id)", to = "(left_id, right_id)")]
107+
pub a: Option<super::composite_a::Entity>,
108+
}
109+
```
110+
111+
<details>
112+
<summary>It's expanded to:</summary>
113+
114+
```rust title="composite_b.rs"
115+
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
116+
pub enum Relation {
117+
#[sea_orm(
118+
belongs_to = "super::composite_a::Entity",
119+
from = "(Column::LeftId, Column::RightId)",
120+
to = "(super::composite_a::Column::LeftId, super::composite_a::Column::RightId)",
121+
)]
122+
CakeFilling,
116123
}
117-
```
124+
```
125+
</details>

SeaORM/docs/06-relation/04-complex-relations.md

Lines changed: 114 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -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"
8583
use 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")]
9088
pub 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")]
131185
pub 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?
145199
By default, `has_many` invokes the `Related` trait to define the relation.
146200
As 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")]
152206
pub 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

SeaORM/docs/12-internal-design/04-diesel.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,6 @@ assert_eq!(
165165
);
166166
```
167167

168-
Trust me, we'll implement automatic migration soon!
169-
170168
(In Diesel it's not possible to go back from schema description to DDL)
171169

172170
## Nested select and other ergonomics

0 commit comments

Comments
 (0)