Skip to main content

toasty_driver_integration_suite/tests/
select_projection_has_one.rs

1//! `.select(...)` projection through a `HasOne` relation field.
2//!
3//! Per PR #827, projecting a `BelongsTo` works because the macro emits
4//! `IntoExpr<TargetModel>` for the relation field-struct and the lowering
5//! walk routes the reference through `build_relation_subquery`.  `HasOne`
6//! uses the same field-struct type (`<Target as Relation>::OneField`) and
7//! `build_relation_subquery` already has a `HasOne` branch (used by
8//! `.include`), so the case works end-to-end with no further production
9//! code change.
10
11use crate::prelude::*;
12
13#[driver_test(requires(sql))]
14pub async fn select_has_one(t: &mut Test) -> Result<()> {
15    #[derive(Debug, toasty::Model)]
16    struct User {
17        #[key]
18        #[auto]
19        id: uuid::Uuid,
20        name: String,
21
22        #[has_one]
23        profile: toasty::Deferred<Profile>,
24    }
25
26    #[derive(Debug, toasty::Model)]
27    struct Profile {
28        #[key]
29        #[auto]
30        id: uuid::Uuid,
31
32        #[unique]
33        user_id: Option<uuid::Uuid>,
34
35        #[belongs_to(key = user_id, references = id)]
36        user: toasty::Deferred<Option<User>>,
37
38        bio: String,
39    }
40
41    let mut db = t.setup_db(models!(User, Profile)).await;
42
43    toasty::create!(User {
44        name: "Alice",
45        profile: Profile::create().bio("apple a day"),
46    })
47    .exec(&mut db)
48    .await?;
49
50    let profiles: Vec<Profile> = User::all()
51        .select(User::fields().profile())
52        .exec(&mut db)
53        .await?;
54
55    assert_eq!(profiles.len(), 1);
56    assert_eq!(profiles[0].bio, "apple a day");
57
58    toasty::create!(User {
59        name: "Bob",
60        profile: Profile::create().bio("beta bio"),
61    })
62    .exec(&mut db)
63    .await?;
64
65    let profiles: Vec<Profile> = User::filter(User::fields().name().eq("Bob"))
66        .select(User::fields().profile())
67        .exec(&mut db)
68        .await?;
69
70    assert_eq!(profiles.len(), 1);
71    assert_eq!(profiles[0].bio, "beta bio");
72
73    let profile: Option<Profile> = User::filter(User::fields().name().eq("Alice"))
74        .select(User::fields().profile())
75        .first()
76        .exec(&mut db)
77        .await?;
78
79    assert_eq!(profile.map(|p| p.bio).as_deref(), Some("apple a day"));
80
81    Ok(())
82}