sea_orm/entity/
link.rs

1use crate::{
2    join_tbl_on_condition, unpack_table_ref, EntityTrait, QuerySelect, RelationDef, Select,
3};
4use sea_query::{Alias, Condition, IntoIden, JoinType, SeaRc};
5
6/// Same as [RelationDef]
7pub type LinkDef = RelationDef;
8
9/// A Trait for links between Entities
10pub trait Linked {
11    #[allow(missing_docs)]
12    type FromEntity: EntityTrait;
13
14    #[allow(missing_docs)]
15    type ToEntity: EntityTrait;
16
17    /// Link for an Entity
18    fn link(&self) -> Vec<LinkDef>;
19
20    /// Find all the Entities that are linked to the Entity
21    fn find_linked(&self) -> Select<Self::ToEntity> {
22        let mut select = Select::new();
23        for (i, mut rel) in self.link().into_iter().rev().enumerate() {
24            let from_tbl = Alias::new(format!("r{i}")).into_iden();
25            let to_tbl = if i > 0 {
26                Alias::new(format!("r{}", i - 1)).into_iden()
27            } else {
28                unpack_table_ref(&rel.to_tbl)
29            };
30            let table_ref = rel.from_tbl;
31
32            let mut condition = Condition::all().add(join_tbl_on_condition(
33                SeaRc::clone(&from_tbl),
34                SeaRc::clone(&to_tbl),
35                rel.from_col,
36                rel.to_col,
37            ));
38            if let Some(f) = rel.on_condition.take() {
39                condition = condition.add(f(SeaRc::clone(&from_tbl), SeaRc::clone(&to_tbl)));
40            }
41
42            select
43                .query()
44                .join_as(JoinType::InnerJoin, table_ref, from_tbl, condition);
45        }
46        select
47    }
48}