Decouple item (class) form from model
This makes it possible to introduce form-only fields without affecting the model.
This commit is contained in:
parent
e3cb717087
commit
7defae7931
|
@ -7,6 +7,7 @@ use std::collections::HashMap;
|
|||
use actix_identity::Identity;
|
||||
use actix_web::{error, get, post, web, Responder};
|
||||
use maud::html;
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -263,10 +264,28 @@ async fn list(pool: web::Data<PgPool>, user: Identity) -> actix_web::Result<impl
|
|||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NewItemForm {
|
||||
pub name: Option<String>,
|
||||
pub parent: Option<Uuid>,
|
||||
pub class: Uuid,
|
||||
pub original_packaging: Option<Uuid>,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NewItemFormPrefilled {
|
||||
pub name: Option<String>,
|
||||
pub parent: Option<Uuid>,
|
||||
pub class: Option<Uuid>,
|
||||
pub original_packaging: Option<Uuid>,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[get("/items/add")]
|
||||
async fn add_form(
|
||||
pool: web::Data<PgPool>,
|
||||
form: web::Query<NewItemForm>,
|
||||
form: web::Query<NewItemFormPrefilled>,
|
||||
user: Identity,
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let datalist_items = datalist::items(&pool)
|
||||
|
@ -340,13 +359,23 @@ async fn add_form(
|
|||
|
||||
#[post("/items/add")]
|
||||
async fn add_post(
|
||||
data: web::Form<NewItem>,
|
||||
data: web::Form<NewItemForm>,
|
||||
pool: web::Data<PgPool>,
|
||||
_user: Identity,
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let item = manage::item::add(&pool, data.into_inner())
|
||||
.await
|
||||
.map_err(error::ErrorInternalServerError)?;
|
||||
let data = data.into_inner();
|
||||
let item = manage::item::add(
|
||||
&pool,
|
||||
NewItem {
|
||||
name: data.name,
|
||||
class: data.class,
|
||||
parent: data.parent,
|
||||
original_packaging: data.original_packaging,
|
||||
description: data.description,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(error::ErrorInternalServerError)?;
|
||||
Ok(web::Redirect::to("/item/".to_owned() + &item.id.to_string()).see_other())
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
use actix_identity::Identity;
|
||||
use actix_web::{error, get, post, web, Responder};
|
||||
use maud::html;
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -230,10 +231,24 @@ async fn list(pool: web::Data<PgPool>, user: Identity) -> actix_web::Result<impl
|
|||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NewItemClassForm {
|
||||
pub name: String,
|
||||
pub parent: Option<Uuid>,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NewItemClassFormPrefilled {
|
||||
pub name: Option<String>,
|
||||
pub parent: Option<Uuid>,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[get("/item-classes/add")]
|
||||
async fn add_form(
|
||||
pool: web::Data<PgPool>,
|
||||
form: web::Query<NewItemClassForm>,
|
||||
form: web::Query<NewItemClassFormPrefilled>,
|
||||
user: Identity,
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let datalist_item_classes = datalist::item_classes(&pool)
|
||||
|
@ -285,13 +300,21 @@ async fn add_form(
|
|||
|
||||
#[post("/item-classes/add")]
|
||||
async fn add(
|
||||
data: web::Form<NewItemClass>,
|
||||
data: web::Form<NewItemClassForm>,
|
||||
pool: web::Data<PgPool>,
|
||||
_user: Identity,
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let item = manage::item_class::add(&pool, data.into_inner())
|
||||
.await
|
||||
.map_err(error::ErrorInternalServerError)?;
|
||||
let data = data.into_inner();
|
||||
let item = manage::item_class::add(
|
||||
&pool,
|
||||
NewItemClass {
|
||||
name: data.name,
|
||||
parent: data.parent,
|
||||
description: data.description,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(error::ErrorInternalServerError)?;
|
||||
Ok(web::Redirect::to("/item-class/".to_owned() + &item.id.to_string()).see_other())
|
||||
}
|
||||
|
||||
|
|
|
@ -36,21 +36,6 @@ pub struct NewItem {
|
|||
pub description: String,
|
||||
}
|
||||
|
||||
// Its structure is not how it could ideally be
|
||||
// (doubly nested Options where the original struct already has an Option>)
|
||||
// because the intended usage (in a GET request parameter) does not allow such fine-grained types.
|
||||
// TODO: this can be automated from NewItem with derive macro
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NewItemForm {
|
||||
#[serde(default)]
|
||||
pub name: Option<String>,
|
||||
#[serde(default)]
|
||||
pub parent: Option<Uuid>,
|
||||
pub class: Option<Uuid>,
|
||||
pub original_packaging: Option<Uuid>,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct ItemClass {
|
||||
pub id: Uuid,
|
||||
|
@ -69,12 +54,3 @@ pub struct NewItemClass {
|
|||
pub parent: Option<Uuid>,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
// see NewItemForm
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NewItemClassForm {
|
||||
pub name: Option<String>,
|
||||
#[serde(default)]
|
||||
pub parent: Option<Uuid>,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue