Trait elephantry::Model

source ·
pub trait Model {
    type Entity: Entity;
    type Structure: Structure;

    // Required method
    fn new(connection: &Connection) -> Self;

    // Provided methods
    fn default_projection() -> Projection { ... }
    fn create_projection() -> Projection { ... }
    fn create_entity(tuple: &Tuple<'_>) -> Self::Entity { ... }
    fn primary_key(
        entity: &Self::Entity
    ) -> Result<HashMap<&'static str, &dyn ToSql>> { ... }
}
Expand description

Impl this trait to create a link between an entity and a structure.

Required Associated Types§

Required Methods§

source

fn new(connection: &Connection) -> Self

Provided Methods§

source

fn default_projection() -> Projection

This method creates a projection based on the structure definition of the underlying relation.

This method can be used where a projection that sticks to table definition is needed like recursive CTEs. For normal projections, use create_projection instead.

source

fn create_projection() -> Projection

This is a helper to create a new projection according to the current structure. Overriding this method will change projection for all models.

Examples found in repository?
examples/08-composite.rs (line 27)
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
        pub fn employee_with_department(&self, id: i32) -> elephantry::Result<Entity> {
            use elephantry::{Model, Projectable};

            let employee_projection = Self::create_projection()
                .unset_field("department_id")
                .add_field("departments", "array_agg(depts)")
                .alias("e")
                .to_string();

            let employee = <Self as elephantry::Model>::Structure::relation();

            let sql = format!(
                r#"
with recursive
    depts (department_id, name, parent_id) as (
        select d.department_id, d.name, d.parent_id from department d join {employee} e using(department_id) where e.employee_id = $1
        union all
        select d.department_id, d.name, d.parent_id from depts parent join department d on parent.parent_id = d.department_id
    )
select {employee_projection}
    from {employee} e, depts
    where e.employee_id = $1
    group by e.employee_id
"#
            );

            Ok(self.connection.query::<Entity>(&sql, &[&id])?.get(0))
        }
More examples
Hide additional examples
examples/07-relations.rs (line 20)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
        pub fn employee_with_department(&self, id: i32) -> elephantry::Result<Entity> {
            use elephantry::{Model, Projectable};

            let employee_projection = Self::create_projection()
                .unset_field("department_id")
                .add_field("departments", "array_agg(depts)")
                .alias("e")
                .to_string();

            let employee = <Self as elephantry::Model>::Structure::relation();

            let department_projection = super::department::Model::create_projection()
                .alias("d")
                .unset_field("parent")
                .to_string();

            let department = super::department::Structure::relation();

            let sql = format!(
                r#"
with recursive
    depts (department_id, name, parent_id) as (
        select {department_projection} from {department} d join {employee} e using(department_id) where e.employee_id = $1
        union all
        select {department_projection} from depts parent join {department} d on parent.parent_id = d.department_id
    )
select {employee_projection}
    from {employee} e, depts
    where e.employee_id = $1
    group by e.employee_id
"#
            );

            Ok(self.connection.query::<Entity>(&sql, &[&id])?.get(0))
        }
source

fn create_entity(tuple: &Tuple<'_>) -> Self::Entity

Create a new entity.

source

fn primary_key( entity: &Self::Entity ) -> Result<HashMap<&'static str, &dyn ToSql>>

Object Safety§

This trait is not object safe.

Implementors§