Skip to main content

toasty_driver_integration_suite/tests/
relation_has_many_boxed_fk.rs

1use crate::prelude::*;
2
3use std::{rc::Rc, sync::Arc};
4
5#[driver_test(requires(sql))]
6pub async fn boxed_u64_fk_crud(test: &mut Test) -> Result<()> {
7    #[derive(Debug, toasty::Model)]
8    struct User {
9        #[key]
10        id: u64,
11        name: String,
12        #[has_many]
13        todos: toasty::HasMany<Todo>,
14    }
15
16    #[derive(Debug, toasty::Model)]
17    struct Todo {
18        #[key]
19        id: u64,
20        #[index]
21        user_id: Box<u64>,
22        #[belongs_to(key = user_id, references = id)]
23        user: toasty::BelongsTo<User>,
24        title: String,
25    }
26
27    let mut db = test.setup_db(models!(User, Todo)).await;
28
29    // Create a user
30    let user = toasty::create!(User {
31        id: 1,
32        name: "Alice"
33    })
34    .exec(&mut db)
35    .await?;
36
37    // No todos yet
38    let todos: Vec<_> = user.todos().exec(&mut db).await?;
39    assert!(todos.is_empty());
40
41    // Create a todo via the has_many association
42    let todo = user
43        .todos()
44        .create()
45        .id(1)
46        .title("Buy groceries")
47        .exec(&mut db)
48        .await?;
49
50    assert_eq!(todo.title, "Buy groceries");
51    assert_eq!(*todo.user_id, user.id);
52
53    // Query back by FK
54    let todos: Vec<_> = Todo::filter_by_user_id(user.id).exec(&mut db).await?;
55    assert_eq!(todos.len(), 1);
56    assert_eq!(todos[0].title, "Buy groceries");
57
58    // Create another todo directly
59    let todo2 = Todo::create()
60        .user(&user)
61        .id(2)
62        .title("Walk the dog")
63        .exec(&mut db)
64        .await?;
65
66    assert_eq!(*todo2.user_id, user.id);
67
68    // List all user's todos
69    let todos: Vec<_> = user.todos().exec(&mut db).await?;
70    assert_eq!(todos.len(), 2);
71
72    // Look up user from todo FK
73    let found_user = User::get_by_id(&mut db, &*todo.user_id).await?;
74    assert_eq!(found_user.id, user.id);
75
76    Ok(())
77}
78
79#[driver_test(requires(sql))]
80pub async fn boxed_u64_fk_batch_create(test: &mut Test) -> Result<()> {
81    #[derive(Debug, toasty::Model)]
82    struct User {
83        #[key]
84        id: u64,
85        name: String,
86        #[has_many]
87        todos: toasty::HasMany<Todo>,
88    }
89
90    #[derive(Debug, toasty::Model)]
91    struct Todo {
92        #[key]
93        id: u64,
94        #[index]
95        user_id: Box<u64>,
96        #[belongs_to(key = user_id, references = id)]
97        user: toasty::BelongsTo<User>,
98        title: String,
99    }
100
101    let mut db = test.setup_db(models!(User, Todo)).await;
102
103    // Create user with todos in one batch
104    let user = User::create()
105        .id(1)
106        .name("Bob")
107        .todo(Todo::create().id(1).title("First task"))
108        .todo(Todo::create().id(2).title("Second task"))
109        .exec(&mut db)
110        .await?;
111
112    let todos: Vec<_> = user.todos().exec(&mut db).await?;
113    assert_eq!(todos.len(), 2);
114
115    for todo in &todos {
116        assert_eq!(*todo.user_id, user.id);
117    }
118
119    Ok(())
120}
121
122#[driver_test(requires(sql))]
123pub async fn boxed_u64_fk_delete_and_update(test: &mut Test) -> Result<()> {
124    #[derive(Debug, toasty::Model)]
125    struct User {
126        #[key]
127        id: u64,
128        name: String,
129        #[has_many]
130        todos: toasty::HasMany<Todo>,
131    }
132
133    #[derive(Debug, toasty::Model)]
134    struct Todo {
135        #[key]
136        id: u64,
137        #[index]
138        user_id: Box<u64>,
139        #[belongs_to(key = user_id, references = id)]
140        user: toasty::BelongsTo<User>,
141        title: String,
142    }
143
144    let mut db = test.setup_db(models!(User, Todo)).await;
145
146    let user = toasty::create!(User {
147        id: 1,
148        name: "Carol"
149    })
150    .exec(&mut db)
151    .await?;
152
153    let mut todo = user
154        .todos()
155        .create()
156        .id(1)
157        .title("Original")
158        .exec(&mut db)
159        .await?;
160
161    // Update the todo title
162    todo.update().title("Updated").exec(&mut db).await?;
163
164    let reloaded = Todo::get_by_id(&mut db, &todo.id).await?;
165    assert_eq!(reloaded.title, "Updated");
166    assert_eq!(*reloaded.user_id, user.id);
167
168    // Delete the todo
169    reloaded.delete().exec(&mut db).await?;
170
171    let todos: Vec<_> = user.todos().exec(&mut db).await?;
172    assert!(todos.is_empty());
173
174    Ok(())
175}
176
177#[driver_test(requires(sql))]
178pub async fn arc_u64_fk_crud(test: &mut Test) -> Result<()> {
179    #[derive(Debug, toasty::Model)]
180    struct User {
181        #[key]
182        id: u64,
183        name: String,
184        #[has_many]
185        todos: toasty::HasMany<Todo>,
186    }
187
188    #[derive(Debug, toasty::Model)]
189    struct Todo {
190        #[key]
191        id: u64,
192        #[index]
193        user_id: Arc<u64>,
194        #[belongs_to(key = user_id, references = id)]
195        user: toasty::BelongsTo<User>,
196        title: String,
197    }
198
199    let mut db = test.setup_db(models!(User, Todo)).await;
200
201    let user = toasty::create!(User {
202        id: 1,
203        name: "Alice"
204    })
205    .exec(&mut db)
206    .await?;
207
208    // Create via association
209    let todo = user
210        .todos()
211        .create()
212        .id(1)
213        .title("Arc task")
214        .exec(&mut db)
215        .await?;
216
217    assert_eq!(*todo.user_id, user.id);
218
219    // Query back by FK
220    let todos: Vec<_> = Todo::filter_by_user_id(user.id).exec(&mut db).await?;
221    assert_eq!(todos.len(), 1);
222    assert_eq!(todos[0].title, "Arc task");
223
224    // Create directly
225    let todo2 = Todo::create()
226        .user(&user)
227        .id(2)
228        .title("Arc task 2")
229        .exec(&mut db)
230        .await?;
231
232    assert_eq!(*todo2.user_id, user.id);
233
234    // Batch create
235    let user2 = User::create()
236        .id(2)
237        .name("Bob")
238        .todo(Todo::create().id(3).title("Batch 1"))
239        .todo(Todo::create().id(4).title("Batch 2"))
240        .exec(&mut db)
241        .await?;
242
243    let todos: Vec<_> = user2.todos().exec(&mut db).await?;
244    assert_eq!(todos.len(), 2);
245
246    for todo in &todos {
247        assert_eq!(*todo.user_id, user2.id);
248    }
249
250    Ok(())
251}
252
253#[driver_test(requires(sql))]
254pub async fn rc_u64_fk_crud(test: &mut Test) -> Result<()> {
255    #[derive(Debug, toasty::Model)]
256    struct User {
257        #[key]
258        id: u64,
259        name: String,
260        #[has_many]
261        todos: toasty::HasMany<Todo>,
262    }
263
264    #[derive(Debug, toasty::Model)]
265    struct Todo {
266        #[key]
267        id: u64,
268        #[index]
269        user_id: Rc<u64>,
270        #[belongs_to(key = user_id, references = id)]
271        user: toasty::BelongsTo<User>,
272        title: String,
273    }
274
275    let mut db = test.setup_db(models!(User, Todo)).await;
276
277    let user = toasty::create!(User {
278        id: 1,
279        name: "Alice"
280    })
281    .exec(&mut db)
282    .await?;
283
284    // Create via association
285    let todo = user
286        .todos()
287        .create()
288        .id(1)
289        .title("Rc task")
290        .exec(&mut db)
291        .await?;
292
293    assert_eq!(*todo.user_id, user.id);
294
295    // Query back by FK
296    let todos: Vec<_> = Todo::filter_by_user_id(user.id).exec(&mut db).await?;
297    assert_eq!(todos.len(), 1);
298    assert_eq!(todos[0].title, "Rc task");
299
300    // Create directly
301    let todo2 = Todo::create()
302        .user(&user)
303        .id(2)
304        .title("Rc task 2")
305        .exec(&mut db)
306        .await?;
307
308    assert_eq!(*todo2.user_id, user.id);
309
310    // Batch create
311    let user2 = User::create()
312        .id(2)
313        .name("Bob")
314        .todo(Todo::create().id(3).title("Batch 1"))
315        .todo(Todo::create().id(4).title("Batch 2"))
316        .exec(&mut db)
317        .await?;
318
319    let todos: Vec<_> = user2.todos().exec(&mut db).await?;
320    assert_eq!(todos.len(), 2);
321
322    for todo in &todos {
323        assert_eq!(*todo.user_id, user2.id);
324    }
325
326    Ok(())
327}