From b00a1e55ed5fa01cb881c387c8e112249070d8ae Mon Sep 17 00:00:00 2001 From: Akshay Date: Thu, 24 Dec 2020 19:27:42 +0530 Subject: add average rating to product listing --- backend/src/handlers/product.rs | 51 +++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'backend/src') diff --git a/backend/src/handlers/product.rs b/backend/src/handlers/product.rs index 41a47a0..0113bc8 100644 --- a/backend/src/handlers/product.rs +++ b/backend/src/handlers/product.rs @@ -74,16 +74,53 @@ pub async fn update_product( } } +#[derive(Serialize, Debug)] +struct CatalogProduct { + pub id: i32, + pub name: String, + pub kind: Option, + pub price: f32, + pub description: Option, + pub average_rating: Option, +} + pub async fn get_all_products(pool: web::Data) -> impl Responder { let conn = pool.get().unwrap(); info!("Generating and returning catalog ..."); - match product.load::(&conn) { - Ok(products) => return HttpResponse::Ok().json(&products), - Err(_) => { - return HttpResponse::InternalServerError() - .body("Unable to fetch product catalog") - } - } + let product_entries = product + .load::(&conn) + .expect("Couldn't connect to DB"); + let with_rating_avg = product_entries + .into_iter() + .map(move |p| { + let rating_list = rating::rating + .filter(rating::product_id.eq(p.id)) + .load::(&conn) + .expect("Coundn't connect to DB") + .into_iter() + .map(|r| r.stars) + .collect::>(); + let (rating_sum, total) = + rating_list.into_iter().fold((0, 0), |(s, t), x| match x { + Some(v) => (s + v, t + 1), + None => (s, t), + }); + let average_rating = if total != 0 { + Some(rating_sum as f64 / total as f64) + } else { + None + }; + CatalogProduct { + average_rating, + name: p.name, + kind: p.kind, + price: p.price, + description: p.description, + id: p.id, + } + }) + .collect::>(); + return HttpResponse::Ok().json(&with_rating_avg); } #[derive(Serialize, Deserialize, Debug)] -- cgit v1.2.3