Try DeriveRelation
This commit is contained in:
parent
0f0d5b52b4
commit
a186338ff5
@ -19,6 +19,8 @@ pub mod field_attr {
|
|||||||
#[derive(Default, FromAttributes)]
|
#[derive(Default, FromAttributes)]
|
||||||
pub struct SeaOrm {
|
pub struct SeaOrm {
|
||||||
pub belongs_to: Option<syn::Lit>,
|
pub belongs_to: Option<syn::Lit>,
|
||||||
|
pub has_one: Option<syn::Lit>,
|
||||||
|
pub has_many: Option<syn::Lit>,
|
||||||
pub from: Option<syn::Lit>,
|
pub from: Option<syn::Lit>,
|
||||||
pub to: Option<syn::Lit>,
|
pub to: Option<syn::Lit>,
|
||||||
}
|
}
|
||||||
|
@ -101,17 +101,18 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
}
|
}
|
||||||
} else if name == "auto_increment" {
|
} else if name == "auto_increment" {
|
||||||
if let Lit::Str(litstr) = &nv.lit {
|
if let Lit::Str(litstr) = &nv.lit {
|
||||||
auto_increment =
|
auto_increment = match litstr.value().as_str() {
|
||||||
match litstr.value().as_str() {
|
|
||||||
"true" => true,
|
"true" => true,
|
||||||
"false" => false,
|
"false" => false,
|
||||||
_ => return Err(Error::new(
|
_ => {
|
||||||
|
return Err(Error::new(
|
||||||
field.span(),
|
field.span(),
|
||||||
format!(
|
format!(
|
||||||
"Invalid auto_increment = {}",
|
"Invalid auto_increment = {}",
|
||||||
litstr.value()
|
litstr.value()
|
||||||
),
|
),
|
||||||
)),
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::iter::FromIterator;
|
use crate::attributes::derive_attr;
|
||||||
use heck::CamelCase;
|
use heck::CamelCase;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote, quote_spanned};
|
use quote::{format_ident, quote, quote_spanned};
|
||||||
use crate::attributes::derive_attr;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
enum Error {
|
enum Error {
|
||||||
InputNotStruct,
|
InputNotStruct,
|
||||||
|
@ -52,32 +52,71 @@ impl DeriveRelation {
|
|||||||
.map(|variant| {
|
.map(|variant| {
|
||||||
let variant_ident = &variant.ident;
|
let variant_ident = &variant.ident;
|
||||||
let attr = field_attr::SeaOrm::from_attributes(&variant.attrs)?;
|
let attr = field_attr::SeaOrm::from_attributes(&variant.attrs)?;
|
||||||
let belongs_to = attr
|
let mut relation_type = quote! { error };
|
||||||
.belongs_to
|
let related_to = if attr.belongs_to.is_some() {
|
||||||
|
relation_type = quote! { belongs_to };
|
||||||
|
attr.belongs_to
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Self::parse_lit_string)
|
.map(Self::parse_lit_string)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
syn::Error::new_spanned(variant, "Missing attribute 'belongs_to'")
|
syn::Error::new_spanned(variant, "Missing value for 'belongs_to'")
|
||||||
})??;
|
})
|
||||||
let from = attr
|
} else if attr.has_one.is_some() {
|
||||||
.from
|
relation_type = quote! { has_one };
|
||||||
|
attr.has_one
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Self::parse_lit_string)
|
.map(Self::parse_lit_string)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
syn::Error::new_spanned(variant, "Missing attribute 'from'")
|
syn::Error::new_spanned(variant, "Missing value for 'has_one'")
|
||||||
|
})
|
||||||
|
} else if attr.has_many.is_some() {
|
||||||
|
relation_type = quote! { has_many };
|
||||||
|
attr.has_many
|
||||||
|
.as_ref()
|
||||||
|
.map(Self::parse_lit_string)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
syn::Error::new_spanned(variant, "Missing value for 'has_many'")
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(syn::Error::new_spanned(
|
||||||
|
variant,
|
||||||
|
"Missing one of 'has_one', 'has_many' or 'belongs_to'",
|
||||||
|
))
|
||||||
|
}??;
|
||||||
|
|
||||||
|
let mut result = quote!(
|
||||||
|
Self::#variant_ident => #entity_ident::#relation_type(#related_to)
|
||||||
|
);
|
||||||
|
|
||||||
|
if attr.from.is_some() {
|
||||||
|
let from =
|
||||||
|
attr.from
|
||||||
|
.as_ref()
|
||||||
|
.map(Self::parse_lit_string)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
syn::Error::new_spanned(variant, "Missing value for 'from'")
|
||||||
})??;
|
})??;
|
||||||
|
result = quote! { #result.from(#from) };
|
||||||
|
} else if attr.belongs_to.is_some() {
|
||||||
|
return Err(syn::Error::new_spanned(variant, "Missing attribute 'from'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if attr.to.is_some() {
|
||||||
let to = attr
|
let to = attr
|
||||||
.to
|
.to
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Self::parse_lit_string)
|
.map(Self::parse_lit_string)
|
||||||
.ok_or_else(|| syn::Error::new_spanned(variant, "Missing attribute 'to'"))??;
|
.ok_or_else(|| {
|
||||||
|
syn::Error::new_spanned(variant, "Missing value for 'to'")
|
||||||
|
})??;
|
||||||
|
result = quote! { #result.to(#to) };
|
||||||
|
} else if attr.belongs_to.is_some() {
|
||||||
|
return Err(syn::Error::new_spanned(variant, "Missing attribute 'to'"));
|
||||||
|
}
|
||||||
|
|
||||||
Result::<_, syn::Error>::Ok(quote!(
|
result = quote! { #result.into() };
|
||||||
Self::#variant_ident => #entity_ident::belongs_to(#belongs_to)
|
|
||||||
.from(#from)
|
Result::<_, syn::Error>::Ok(result)
|
||||||
.to(#to)
|
|
||||||
.into()
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
error::*, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,
|
||||||
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
||||||
DeriveEntityModel, DeriveModel, DerivePrimaryKey, EntityName, EntityTrait, EnumIter,
|
DeriveEntityModel, DeriveModel, DerivePrimaryKey, DeriveRelation, EntityName, EntityTrait,
|
||||||
ForeignKeyAction, Iden, IdenStatic, Linked, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait,
|
EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, ModelTrait, PrimaryKeyToColumn,
|
||||||
QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select, Value,
|
PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "with-json")]
|
#[cfg(feature = "with-json")]
|
||||||
|
@ -227,7 +227,7 @@ pub use query::*;
|
|||||||
|
|
||||||
pub use sea_orm_macros::{
|
pub use sea_orm_macros::{
|
||||||
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, DeriveCustomColumn, DeriveEntity,
|
||||||
DeriveEntityModel, DeriveModel, DerivePrimaryKey, FromQueryResult,
|
DeriveEntityModel, DeriveModel, DerivePrimaryKey, DeriveRelation, FromQueryResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use sea_query;
|
pub use sea_query;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate as sea_orm;
|
use crate as sea_orm;
|
||||||
use sea_orm::entity::prelude::*;
|
use crate::entity::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveModel, DeriveActiveModel)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveModel, DeriveActiveModel)]
|
||||||
#[sea_orm(table_name = "cake")]
|
#[sea_orm(table_name = "cake")]
|
||||||
@ -9,19 +9,12 @@ pub struct Model {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
pub enum Relation {
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
Fruit,
|
Fruit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelationTrait for Relation {
|
|
||||||
fn def(&self) -> RelationDef {
|
|
||||||
match self {
|
|
||||||
Self::Fruit => Entity::has_many(super::fruit::Entity).into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<super::fruit::Entity> for Entity {
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::Fruit.def()
|
Relation::Fruit.def()
|
||||||
|
@ -32,8 +32,13 @@ impl PrimaryKeyTrait for PrimaryKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
pub enum Relation {
|
pub enum Relation {
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::cake::Entity",
|
||||||
|
from = "Column::CakeId",
|
||||||
|
to = "super::cake::Column::Id"
|
||||||
|
)]
|
||||||
Cake,
|
Cake,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,17 +54,6 @@ impl ColumnTrait for Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelationTrait for Relation {
|
|
||||||
fn def(&self) -> RelationDef {
|
|
||||||
match self {
|
|
||||||
Self::Cake => Entity::belongs_to(super::cake::Entity)
|
|
||||||
.from(Column::CakeId)
|
|
||||||
.to(super::cake::Column::Id)
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Related<super::cake::Entity> for Entity {
|
impl Related<super::cake::Entity> for Entity {
|
||||||
fn to() -> RelationDef {
|
fn to() -> RelationDef {
|
||||||
Relation::Cake.def()
|
Relation::Cake.def()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user