Skip to main content

toasty_core/schema/app/relation/
has_many.rs

1use crate::{
2    schema::app::{BelongsTo, FieldId, Model, ModelId, Name, Schema},
3    stmt,
4};
5
6/// The inverse side of a one-to-many relationship.
7///
8/// A `HasMany` field on model A means "A has many Bs". The actual foreign key
9/// lives on model B as a [`BelongsTo`] field pointing back at A. The two
10/// sides are linked via the [`pair`](HasMany::pair) field.
11///
12/// # Examples
13///
14/// ```ignore
15/// // Given a `User` model that has many `Post`s:
16/// let has_many: &HasMany = user_field.ty.as_has_many_unwrap();
17/// let post_model = has_many.target(&schema);
18/// let inverse = has_many.pair(&schema); // the BelongsTo on Post
19/// ```
20#[derive(Debug, Clone)]
21pub struct HasMany {
22    /// The [`ModelId`] of the associated (target) model.
23    pub target: ModelId,
24
25    /// The expression type this field evaluates to from the application's
26    /// perspective.
27    pub expr_ty: stmt::Type,
28
29    /// The singular name for one associated item (used in generated method
30    /// names).
31    pub singular: Name,
32
33    /// The [`BelongsTo`] field on the target model that pairs with this
34    /// relation. If a `#[has_many(pair = <field>)]` was supplied, the macro
35    /// resolves this at schema-construction time via `field_name_to_id` on
36    /// the target. Otherwise the linker fills it in by searching the target
37    /// model for a unique `BelongsTo` back to the source.
38    pub pair: FieldId,
39}
40
41impl HasMany {
42    /// Resolves the target [`Model`] from the given schema.
43    pub fn target<'a>(&self, schema: &'a Schema) -> &'a Model {
44        schema.model(self.target)
45    }
46
47    /// Resolves the paired [`BelongsTo`] relation on the target model.
48    ///
49    /// # Panics
50    ///
51    /// Panics if the paired field is not a `BelongsTo` variant.
52    pub fn pair<'a>(&self, schema: &'a Schema) -> &'a BelongsTo {
53        schema.field(self.pair).ty.as_belongs_to_unwrap()
54    }
55}