Skip to main content

toasty_driver_integration_suite/scenarios/
user_org_project_todo.rs

1use crate::prelude::*;
2
3scenario! {
4    //! A 3-step has_many via chain: `User` → `Organization` → `Project` → `Todo`.
5    //!
6    //! Used by tests that need a `via` path longer than the 2-step
7    //! `user_comment_article` scenario.
8    //!
9    //! `User::todos` is the flat 3-step via (`organizations.projects.todos`).
10    //! `User::nested_todos` reaches the same todos through `organizations.todos`,
11    //! where `Organization::todos` is itself a via — a via-of-via, used to test
12    //! recursive flattening of a via path whose step names another via.
13
14    #![id(ID)]
15
16    #[derive(Debug, toasty::Model)]
17    struct User {
18        #[key]
19        #[auto]
20        id: ID,
21
22        name: String,
23
24        #[has_many]
25        organizations: toasty::Deferred<Vec<Organization>>,
26
27        // User → organizations → projects → todos
28        #[has_many(via = organizations.projects.todos)]
29        todos: toasty::Deferred<Vec<Todo>>,
30
31        // User → organizations → Organization::todos, which is itself a via.
32        // The second step expands into another via path (via-of-via).
33        #[has_many(via = organizations.todos)]
34        nested_todos: toasty::Deferred<Vec<Todo>>,
35
36        // A via-of-via with a *scalar* terminal: the chain routes through
37        // `Organization::todos` (itself a via), then projects `Todo::title`.
38        // Exercises the nested-via splice on the scalar-terminal code paths.
39        #[has_many(via = organizations.todos.title)]
40        nested_todo_titles: toasty::Deferred<Vec<String>>,
41    }
42
43    #[derive(Debug, toasty::Model)]
44    struct Organization {
45        #[key]
46        #[auto]
47        id: ID,
48
49        name: String,
50
51        #[index]
52        user_id: ID,
53
54        #[belongs_to(key = user_id, references = id)]
55        user: toasty::Deferred<User>,
56
57        #[has_many]
58        projects: toasty::Deferred<Vec<Project>>,
59
60        // Organization → projects → todos. The via that `User::nested_todos`
61        // routes through, making that relation a via-of-via.
62        #[has_many(via = projects.todos)]
63        todos: toasty::Deferred<Vec<Todo>>,
64    }
65
66    #[derive(Debug, toasty::Model)]
67    struct Project {
68        #[key]
69        #[auto]
70        id: ID,
71
72        name: String,
73
74        #[index]
75        organization_id: ID,
76
77        #[belongs_to(key = organization_id, references = id)]
78        organization: toasty::Deferred<Organization>,
79
80        #[has_many]
81        todos: toasty::Deferred<Vec<Todo>>,
82    }
83
84    #[derive(Debug, toasty::Model)]
85    struct Todo {
86        #[key]
87        #[auto]
88        id: ID,
89
90        title: String,
91
92        #[index]
93        project_id: ID,
94
95        #[belongs_to(key = project_id, references = id)]
96        project: toasty::Deferred<Project>,
97    }
98
99    async fn setup(test: &mut Test) -> toasty::Db {
100        test.setup_db(models!(User, Organization, Project, Todo)).await
101    }
102}