Skip to main content

toasty_driver_integration_suite/tests/
select_projection_belongs_to.rs

1//! `.select(...)` projection through a `BelongsTo` relation field.
2//!
3//! Projects the related-model side of the relation directly: a query rooted
4//! at the source model returns one related-model record per source row.
5
6use crate::prelude::*;
7
8#[driver_test(id(ID), requires(scan))]
9pub async fn select_belongs_to_basic(t: &mut Test) -> Result<()> {
10    #[derive(Debug, toasty::Model)]
11    struct User {
12        #[key]
13        #[auto]
14        id: ID,
15        name: String,
16    }
17
18    #[derive(Debug, toasty::Model)]
19    struct Post {
20        #[key]
21        #[auto]
22        id: ID,
23        title: String,
24
25        #[index]
26        author_id: ID,
27
28        #[belongs_to(key = author_id, references = id)]
29        author: toasty::BelongsTo<User>,
30    }
31
32    let mut db = t.setup_db(models!(User, Post)).await;
33
34    let alice = toasty::create!(User { name: "Alice" })
35        .exec(&mut db)
36        .await?;
37    toasty::create!(Post {
38        title: "Hello",
39        author: alice
40    })
41    .exec(&mut db)
42    .await?;
43
44    let users: Vec<User> = Post::all()
45        .select(Post::fields().author())
46        .exec(&mut db)
47        .await?;
48
49    assert_eq!(users.len(), 1);
50    assert_eq!(users[0].name, "Alice");
51    Ok(())
52}
53
54#[driver_test(id(ID), requires(scan))]
55pub async fn select_belongs_to_with_filter(t: &mut Test) -> Result<()> {
56    #[derive(Debug, toasty::Model)]
57    struct User {
58        #[key]
59        #[auto]
60        id: ID,
61        name: String,
62    }
63
64    #[derive(Debug, toasty::Model)]
65    struct Post {
66        #[key]
67        #[auto]
68        id: ID,
69        title: String,
70
71        #[index]
72        author_id: ID,
73
74        #[belongs_to(key = author_id, references = id)]
75        author: toasty::BelongsTo<User>,
76    }
77
78    let mut db = t.setup_db(models!(User, Post)).await;
79
80    let alice = toasty::create!(User { name: "Alice" })
81        .exec(&mut db)
82        .await?;
83    let bob = toasty::create!(User { name: "Bob" }).exec(&mut db).await?;
84    toasty::create!(Post::[
85        { title: "Alpha", author: alice },
86        { title: "Beta",  author: bob },
87    ])
88    .exec(&mut db)
89    .await?;
90
91    let users: Vec<User> = Post::filter(Post::fields().title().eq("Beta"))
92        .select(Post::fields().author())
93        .exec(&mut db)
94        .await?;
95
96    assert_eq!(users.len(), 1);
97    assert_eq!(users[0].name, "Bob");
98    Ok(())
99}
100
101#[driver_test(id(ID), requires(scan))]
102pub async fn select_belongs_to_first(t: &mut Test) -> Result<()> {
103    #[derive(Debug, toasty::Model)]
104    struct User {
105        #[key]
106        #[auto]
107        id: ID,
108        name: String,
109    }
110
111    #[derive(Debug, toasty::Model)]
112    struct Post {
113        #[key]
114        #[auto]
115        id: ID,
116        title: String,
117
118        #[index]
119        author_id: ID,
120
121        #[belongs_to(key = author_id, references = id)]
122        author: toasty::BelongsTo<User>,
123    }
124
125    let mut db = t.setup_db(models!(User, Post)).await;
126
127    let alice = toasty::create!(User { name: "Alice" })
128        .exec(&mut db)
129        .await?;
130    toasty::create!(Post {
131        title: "Hello",
132        author: alice
133    })
134    .exec(&mut db)
135    .await?;
136
137    let user: Option<User> = Post::filter(Post::fields().title().eq("Hello"))
138        .select(Post::fields().author())
139        .first()
140        .exec(&mut db)
141        .await?;
142
143    assert_eq!(user.map(|u| u.name).as_deref(), Some("Alice"));
144    Ok(())
145}