Find related

This commit is contained in:
Chris Tsang 2021-05-09 02:14:40 +08:00
parent 89af820f2c
commit df03a78702
4 changed files with 51 additions and 9 deletions

View File

@ -49,7 +49,7 @@ pub trait EntityTrait: Iden + Default + Debug + 'static {
/// ); /// );
/// ``` /// ```
fn find() -> Select<Self> { fn find() -> Select<Self> {
Select::new(Self::default()) Select::<Self>::new()
} }
/// ``` /// ```

View File

@ -1,4 +1,4 @@
use super::{Identity, IntoIdentity}; use crate::{EntityTrait, Identity, IntoIdentity, Select};
use sea_query::{Iden, IntoIden}; use sea_query::{Iden, IntoIden};
use std::fmt::Debug; use std::fmt::Debug;
use std::rc::Rc; use std::rc::Rc;
@ -14,6 +14,17 @@ pub trait RelationTrait: Debug + 'static {
fn rel_def(&self) -> RelationDef; fn rel_def(&self) -> RelationDef;
} }
pub trait Related<R>
where
R: EntityTrait,
{
fn via() -> RelationDef;
fn find_related() -> Select<R> {
Select::<R>::new().prepare_reverse_join(Self::via())
}
}
pub struct RelationDef { pub struct RelationDef {
pub rel_type: RelationType, pub rel_type: RelationType,
pub from_tbl: Rc<dyn Iden>, pub from_tbl: Rc<dyn Iden>,

View File

@ -18,7 +18,7 @@ impl<E: 'static> Select<E>
where where
E: EntityTrait, E: EntityTrait,
{ {
pub(crate) fn new(_: E) -> Self { pub(crate) fn new() -> Self {
Self { Self {
query: SelectStatement::new(), query: SelectStatement::new(),
entity: PhantomData, entity: PhantomData,
@ -56,11 +56,7 @@ where
self self
} }
pub fn reverse_join<R>(mut self, rel: R) -> Self pub(crate) fn prepare_reverse_join(mut self, rel: RelationDef) -> Self {
where
R: RelationTrait,
{
let rel = rel.rel_def();
let from_tbl = rel.from_tbl.clone(); let from_tbl = rel.from_tbl.clone();
let to_tbl = rel.to_tbl.clone(); let to_tbl = rel.to_tbl.clone();
let owner_keys = rel.from_col; let owner_keys = rel.from_col;
@ -135,6 +131,13 @@ where
self.prepare_join(JoinType::InnerJoin, E::Relation::rel_def(&rel)) self.prepare_join(JoinType::InnerJoin, E::Relation::rel_def(&rel))
} }
pub fn reverse_join<R>(self, rel: R) -> Self
where
R: RelationTrait,
{
self.prepare_reverse_join(rel.rel_def())
}
/// Get a mutable ref to the query builder /// Get a mutable ref to the query builder
pub fn query(&mut self) -> &mut SelectStatement { pub fn query(&mut self) -> &mut SelectStatement {
&mut self.query &mut self.query
@ -211,4 +214,20 @@ mod tests {
.join(" ") .join(" ")
); );
} }
#[test]
fn join_4() {
assert_eq!(
cake::Entity::find_fruit()
.filter(cake::Column::Id.eq(11))
.build(MysqlQueryBuilder)
.to_string(),
[
"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`",
"INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`",
"WHERE `cake`.`id` = 11",
]
.join(" ")
);
}
} }

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, Identity, IntoIdentity, ModelTrait, ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, Identity, IntoIdentity, ModelTrait,
QueryResult, RelationDef, RelationTrait, TypeErr, QueryResult, Related, RelationDef, RelationTrait, Select, TypeErr,
}; };
#[derive(Default, Debug, Iden)] #[derive(Default, Debug, Iden)]
@ -66,3 +66,15 @@ impl RelationTrait for Relation {
} }
} }
} }
impl Related<super::fruit::Entity> for Entity {
fn via() -> RelationDef {
Relation::Fruit.rel_def()
}
}
impl Entity {
pub fn find_fruit() -> Select<super::fruit::Entity> {
Self::find_related()
}
}