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(scan))]
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::Deferred<Vec<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::Deferred<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    // Create user with todos in one batch
77    let user = User::create()
78        .id(2)
79        .name("Bob")
80        .todos([Todo::create().id(3).title("First task")])
81        .todos([Todo::create().id(4).title("Second task")])
82        .exec(&mut db)
83        .await?;
84
85    let todos: Vec<_> = user.todos().exec(&mut db).await?;
86    assert_eq!(todos.len(), 2);
87
88    for todo in &todos {
89        assert_eq!(*todo.user_id, user.id);
90    }
91
92    let user = toasty::create!(User {
93        id: 3,
94        name: "Carol"
95    })
96    .exec(&mut db)
97    .await?;
98
99    let mut todo = user
100        .todos()
101        .create()
102        .id(5)
103        .title("Original")
104        .exec(&mut db)
105        .await?;
106
107    // Update the todo title
108    todo.update().title("Updated").exec(&mut db).await?;
109
110    let reloaded = Todo::get_by_id(&mut db, &todo.id).await?;
111    assert_eq!(reloaded.title, "Updated");
112    assert_eq!(*reloaded.user_id, user.id);
113
114    // Delete the todo
115    reloaded.delete().exec(&mut db).await?;
116
117    let todos: Vec<_> = user.todos().exec(&mut db).await?;
118    assert!(todos.is_empty());
119
120    Ok(())
121}
122
123#[driver_test(requires(scan))]
124pub async fn arc_u64_fk_crud(test: &mut Test) -> Result<()> {
125    #[derive(Debug, toasty::Model)]
126    struct User {
127        #[key]
128        id: u64,
129        name: String,
130        #[has_many]
131        todos: toasty::Deferred<Vec<Todo>>,
132    }
133
134    #[derive(Debug, toasty::Model)]
135    struct Todo {
136        #[key]
137        id: u64,
138        #[index]
139        user_id: Arc<u64>,
140        #[belongs_to(key = user_id, references = id)]
141        user: toasty::Deferred<User>,
142        title: String,
143    }
144
145    let mut db = test.setup_db(models!(User, Todo)).await;
146
147    let user = toasty::create!(User {
148        id: 1,
149        name: "Alice"
150    })
151    .exec(&mut db)
152    .await?;
153
154    // Create via association
155    let todo = user
156        .todos()
157        .create()
158        .id(1)
159        .title("Arc task")
160        .exec(&mut db)
161        .await?;
162
163    assert_eq!(*todo.user_id, user.id);
164
165    // Query back by FK
166    let todos: Vec<_> = Todo::filter_by_user_id(user.id).exec(&mut db).await?;
167    assert_eq!(todos.len(), 1);
168    assert_eq!(todos[0].title, "Arc task");
169
170    // Create directly
171    let todo2 = Todo::create()
172        .user(&user)
173        .id(2)
174        .title("Arc task 2")
175        .exec(&mut db)
176        .await?;
177
178    assert_eq!(*todo2.user_id, user.id);
179
180    // Batch create
181    let user2 = User::create()
182        .id(2)
183        .name("Bob")
184        .todos([Todo::create().id(3).title("Batch 1")])
185        .todos([Todo::create().id(4).title("Batch 2")])
186        .exec(&mut db)
187        .await?;
188
189    let todos: Vec<_> = user2.todos().exec(&mut db).await?;
190    assert_eq!(todos.len(), 2);
191
192    for todo in &todos {
193        assert_eq!(*todo.user_id, user2.id);
194    }
195
196    Ok(())
197}
198
199#[driver_test(requires(scan))]
200pub async fn rc_u64_fk_crud(test: &mut Test) -> Result<()> {
201    #[derive(Debug, toasty::Model)]
202    struct User {
203        #[key]
204        id: u64,
205        name: String,
206        #[has_many]
207        todos: toasty::Deferred<Vec<Todo>>,
208    }
209
210    #[derive(Debug, toasty::Model)]
211    struct Todo {
212        #[key]
213        id: u64,
214        #[index]
215        user_id: Rc<u64>,
216        #[belongs_to(key = user_id, references = id)]
217        user: toasty::Deferred<User>,
218        title: String,
219    }
220
221    let mut db = test.setup_db(models!(User, Todo)).await;
222
223    let user = toasty::create!(User {
224        id: 1,
225        name: "Alice"
226    })
227    .exec(&mut db)
228    .await?;
229
230    // Create via association
231    let todo = user
232        .todos()
233        .create()
234        .id(1)
235        .title("Rc task")
236        .exec(&mut db)
237        .await?;
238
239    assert_eq!(*todo.user_id, user.id);
240
241    // Query back by FK
242    let todos: Vec<_> = Todo::filter_by_user_id(user.id).exec(&mut db).await?;
243    assert_eq!(todos.len(), 1);
244    assert_eq!(todos[0].title, "Rc task");
245
246    // Create directly
247    let todo2 = Todo::create()
248        .user(&user)
249        .id(2)
250        .title("Rc task 2")
251        .exec(&mut db)
252        .await?;
253
254    assert_eq!(*todo2.user_id, user.id);
255
256    // Batch create
257    let user2 = User::create()
258        .id(2)
259        .name("Bob")
260        .todos([Todo::create().id(3).title("Batch 1")])
261        .todos([Todo::create().id(4).title("Batch 2")])
262        .exec(&mut db)
263        .await?;
264
265    let todos: Vec<_> = user2.todos().exec(&mut db).await?;
266    assert_eq!(todos.len(), 2);
267
268    for todo in &todos {
269        assert_eq!(*todo.user_id, user2.id);
270    }
271
272    Ok(())
273}