regalade/src/routes/recipe.rs

63 lines
2.2 KiB
Rust
Raw Normal View History

2023-06-22 22:29:53 +02:00
use api::{CreateRecipeRequest, CreateRecipeResponse};
use axum::{extract::State, Json};
use sea_orm::{prelude::*, ActiveValue, TransactionTrait};
use crate::entity::{ingredient, prelude::*, recipe, recipe_ingerdients, recipe_steps};
use super::{household::AuthorizedHousehold, AppState, JsonResult, RouteError};
pub(super) async fn create_recipe(
AuthorizedHousehold(household): AuthorizedHousehold,
State(state): State<AppState>,
Json(request): Json<CreateRecipeRequest>,
) -> JsonResult<CreateRecipeResponse> {
let id = state
.db
.transaction(|txn| {
Box::pin(async move {
let model = recipe::ActiveModel {
name: ActiveValue::Set(request.name),
ranking: ActiveValue::Set(request.rating as i32),
..Default::default()
};
let recipe = model.insert(txn).await?;
for (num, text) in request.steps.into_iter().enumerate() {
let model = recipe_steps::ActiveModel {
num: ActiveValue::Set(num as _),
recipe_id: ActiveValue::Set(recipe.id),
text: ActiveValue::Set(text),
};
model.insert(txn).await?;
}
for (ig, amount) in request.ingredients {
if 0 == household
.find_related(Ingredient)
.filter(ingredient::Column::Id.eq(ig))
.count(txn)
.await?
{
Err(RouteError::InvalidRequest(format!(
"No such ingredient {ig}"
)))?;
}
let model = recipe_ingerdients::ActiveModel {
recipe_id: ActiveValue::Set(recipe.id),
ingredient_id: ActiveValue::Set(ig),
amount: ActiveValue::Set(amount),
};
model.insert(txn).await?;
}
Ok(recipe.id)
})
})
.await?;
Ok(CreateRecipeResponse { id }.into())
}