impl selectlist for foreign key
This commit is contained in:
parent
b56bdf8984
commit
a6edbc0f56
@ -12,14 +12,19 @@ use struct_fields::{
|
||||
};
|
||||
|
||||
mod selectlist_fields;
|
||||
use selectlist_fields::{get_select_list, get_select_lists};
|
||||
use selectlist_fields::{get_select_list_from_enum, get_select_list_from_model, get_select_lists};
|
||||
|
||||
mod attributes;
|
||||
mod model_fields;
|
||||
|
||||
#[proc_macro_derive(DeriveActixAdminSelectList, attributes(actix_admin))]
|
||||
pub fn derive_actix_admin_select_list(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
get_select_list(input)
|
||||
#[proc_macro_derive(DeriveActixAdminEnumSelectList, attributes(actix_admin))]
|
||||
pub fn derive_actix_admin_enum_select_list(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
get_select_list_from_enum(input)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(DeriveActixAdminModelSelectList, attributes(actix_admin))]
|
||||
pub fn derive_actix_admin_model_select_list(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
get_select_list_from_model(input)
|
||||
}
|
||||
|
||||
#[proc_macro_derive(DeriveActixAdmin, attributes(actix_admin))]
|
||||
@ -70,15 +75,16 @@ pub fn derive_actix_admin_view_model(input: proc_macro::TokenStream) -> proc_mac
|
||||
entities
|
||||
}
|
||||
|
||||
async fn create_entity(db: &DatabaseConnection, mut model: ActixAdminModel) -> ActixAdminModel {
|
||||
let mut validation_errs = Entity::validate_model(&model);
|
||||
//model.errors.append(&mut validation_errs);
|
||||
model.errors = validation_errs;
|
||||
fn validate_entity(model: &mut ActixAdminModel) {
|
||||
Entity::validate_model(model);
|
||||
|
||||
if !model.has_errors() {
|
||||
let custom_errors = Entity::validate(&model);
|
||||
model.custom_errors = custom_errors;
|
||||
}
|
||||
|
||||
async fn create_entity(db: &DatabaseConnection, mut model: ActixAdminModel) -> ActixAdminModel {
|
||||
let new_model = ActiveModel::from(model.clone());
|
||||
let insert_operation = Entity::insert(new_model).exec(db).await;
|
||||
}
|
||||
|
||||
model
|
||||
}
|
||||
@ -91,17 +97,12 @@ pub fn derive_actix_admin_view_model(input: proc_macro::TokenStream) -> proc_mac
|
||||
}
|
||||
|
||||
async fn edit_entity(db: &DatabaseConnection, id: i32, mut model: ActixAdminModel) -> ActixAdminModel {
|
||||
let mut validation_errs = Entity::validate_model(&model);
|
||||
//model.errors.append(&mut validation_errs);
|
||||
model.errors=validation_errs;
|
||||
|
||||
if !model.has_errors() {
|
||||
let entity: Option<Model> = Entity::find_by_id(id).one(db).await.unwrap();
|
||||
let mut entity: ActiveModel = entity.unwrap().into();
|
||||
|
||||
#(#fields_for_edit_model);*;
|
||||
let entity: Model = entity.update(db).await.unwrap();
|
||||
}
|
||||
|
||||
model
|
||||
}
|
||||
|
||||
@ -152,7 +153,8 @@ pub fn derive_actix_admin_model(input: proc_macro::TokenStream) -> proc_macro::T
|
||||
values: hashmap![
|
||||
#(#fields_for_from_model),*
|
||||
],
|
||||
errors: HashMap::new()
|
||||
errors: HashMap::new(),
|
||||
custom_errors: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,12 +196,11 @@ pub fn derive_actix_admin_model(input: proc_macro::TokenStream) -> proc_macro::T
|
||||
(num_pages, model_entities)
|
||||
}
|
||||
|
||||
fn validate_model(model: &ActixAdminModel) -> HashMap<String, String> {
|
||||
fn validate_model(model: &mut ActixAdminModel) {
|
||||
let mut errors = HashMap::<String, String>::new();
|
||||
#(#fields_for_validate_model);*;
|
||||
//let mut custom_errors = Entity.validate();
|
||||
//errors.append(&mut custom_errors);
|
||||
errors
|
||||
|
||||
model.errors = errors;
|
||||
}
|
||||
|
||||
fn get_fields() -> Vec<ActixAdminViewModelField> {
|
||||
|
@ -5,13 +5,37 @@ use quote::quote;
|
||||
use crate::model_fields::{ ModelField };
|
||||
use proc_macro2::{Span};
|
||||
|
||||
pub fn get_select_list(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn get_select_list_from_model(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
//let ast: DeriveInput = syn::parse(input).unwrap();
|
||||
//let (_vis, _ty, _generics) = (&ast.vis, &ast.ident, &ast.generics);
|
||||
|
||||
let expanded = quote! {
|
||||
#[async_trait]
|
||||
impl ActixAdminSelectListTrait for Entity {
|
||||
async fn get_key_value(db: &DatabaseConnection) -> Vec<(String, String)> {
|
||||
let entities = Entity::find().order_by_asc(Column::Id).all(db).await;
|
||||
let mut key_value = Vec::new();
|
||||
|
||||
for entity in entities.unwrap() {
|
||||
key_value.push((entity.id.to_string(), entity.to_string()));
|
||||
};
|
||||
key_value.sort_by(|a, b| a.1.cmp(&b.1));
|
||||
key_value
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
pub fn get_select_list_from_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let ast: DeriveInput = syn::parse(input).unwrap();
|
||||
let (_vis, ty, _generics) = (&ast.vis, &ast.ident, &ast.generics);
|
||||
|
||||
let expanded = quote! {
|
||||
#[async_trait]
|
||||
impl ActixAdminSelectListTrait for #ty {
|
||||
fn get_key_value() -> Vec<(String, String)> {
|
||||
async fn get_key_value(db: &DatabaseConnection) -> Vec<(String, String)> {
|
||||
let mut fields = Vec::new();
|
||||
for field in #ty::iter() {
|
||||
fields.push((field.to_string(), field.to_string()));
|
||||
@ -20,6 +44,7 @@ pub fn get_select_list(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
@ -31,7 +56,7 @@ pub fn get_select_lists(fields: &Vec<ModelField>) -> Vec<proc_macro2::TokenStrea
|
||||
let ident_name = model_field.ident.to_string();
|
||||
let select_list_ident = Ident::new(&(model_field.select_list), Span::call_site());
|
||||
quote! {
|
||||
#ident_name => #select_list_ident::get_key_value()
|
||||
#ident_name => #select_list_ident::get_key_value(db).await
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
|
@ -4,6 +4,7 @@ use std::collections::HashMap;
|
||||
use tera::{Tera, Result, to_value, try_get_value };
|
||||
use std::{ hash::BuildHasher};
|
||||
use actix_session::{Session};
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub mod view_model;
|
||||
pub mod model;
|
||||
@ -14,7 +15,7 @@ pub mod prelude {
|
||||
pub use crate::builder::{ ActixAdminBuilder, ActixAdminBuilderTrait};
|
||||
pub use crate::model::{ ActixAdminModel, ActixAdminModelTrait};
|
||||
pub use crate::view_model::{ ActixAdminViewModel, ActixAdminViewModelTrait, ActixAdminViewModelField, ActixAdminViewModelSerializable, ActixAdminViewModelFieldType };
|
||||
pub use actix_admin_macros::{ DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel, DeriveActixAdminSelectList };
|
||||
pub use actix_admin_macros::{ DeriveActixAdmin, DeriveActixAdminModel, DeriveActixAdminViewModel, DeriveActixAdminEnumSelectList, DeriveActixAdminModelSelectList };
|
||||
pub use crate::{ ActixAdminAppDataTrait, ActixAdmin, ActixAdminConfiguration };
|
||||
pub use crate::{ hashmap, ActixAdminSelectListTrait };
|
||||
}
|
||||
@ -88,8 +89,9 @@ pub trait ActixAdminAppDataTrait {
|
||||
}
|
||||
|
||||
// SelectListTrait
|
||||
#[async_trait]
|
||||
pub trait ActixAdminSelectListTrait {
|
||||
fn get_key_value() -> Vec<(String, String)>;
|
||||
async fn get_key_value(db: &DatabaseConnection) -> Vec<(String, String)>;
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,9 +16,9 @@ pub trait ActixAdminModelTrait {
|
||||
search: &String
|
||||
) -> (usize, Vec<ActixAdminModel>);
|
||||
fn get_fields() -> Vec<ActixAdminViewModelField>;
|
||||
fn validate_model(model: &ActixAdminModel) -> HashMap<String, String>;
|
||||
fn validate_model(model: &mut ActixAdminModel);
|
||||
// function to be overridable for custom error handling
|
||||
fn validate(&self) -> HashMap<String, String> {
|
||||
fn validate(_model: &ActixAdminModel) -> HashMap<String, String> {
|
||||
return HashMap::new();
|
||||
}
|
||||
}
|
||||
@ -28,6 +28,7 @@ pub struct ActixAdminModel {
|
||||
pub primary_key: Option<String>,
|
||||
pub values: HashMap<String, String>,
|
||||
pub errors: HashMap<String, String>,
|
||||
pub custom_errors: HashMap<String, String>
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +38,7 @@ impl ActixAdminModel {
|
||||
primary_key: None,
|
||||
values: HashMap::new(),
|
||||
errors: HashMap::new(),
|
||||
custom_errors: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +65,7 @@ impl ActixAdminModel {
|
||||
primary_key: None,
|
||||
values: hashmap,
|
||||
errors: HashMap::new(),
|
||||
custom_errors: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,8 @@ async fn create_or_edit_post<T: ActixAdminAppDataTrait, E: ActixAdminViewModelTr
|
||||
}
|
||||
|
||||
let db = &data.get_db();
|
||||
let model = ActixAdminModel::create_from_payload(payload).await.unwrap();
|
||||
let mut model = ActixAdminModel::create_from_payload(payload).await.unwrap();
|
||||
E::validate_entity(&mut model);
|
||||
|
||||
if model.has_errors() {
|
||||
let mut ctx = Context::new();
|
||||
|
@ -21,6 +21,7 @@ pub trait ActixAdminViewModelTrait {
|
||||
async fn get_entity(db: &DatabaseConnection, id: i32) -> ActixAdminModel;
|
||||
async fn edit_entity(db: &DatabaseConnection, id: i32, model: ActixAdminModel) -> ActixAdminModel;
|
||||
async fn get_select_lists(db: &DatabaseConnection) -> HashMap<String, Vec<(String, String)>>;
|
||||
fn validate_entity(model: &mut ActixAdminModel);
|
||||
|
||||
fn get_entity_name() -> String;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user