Search⌘ K
AI Features

Update and Delete Resources

Explore how to update and delete database resources in Rust web applications. Learn to use helper structs with AsChangeset for efficient updates and implement cascading deletes using SQL to maintain database integrity. This lesson includes practical testing techniques to ensure reliable data manipulation.

We'll cover the following...

Update

Updating a resource might be a bit tricky, so we’re going to need a few helper structs. We’ll use the annotation AsChangeset for the struct we directly modify in the database.

We have the option to refactor the structs used for inserting, but in our case, we’ll create new ones for this purpose.

Rust 1.40.0
#[derive(Insertable, Queryable, AsChangeset, Debug, Clone, Serialize, Deserialize)]
#[table_name="variants"]
pub struct FormVariant {
pub id: Option<i32>,
pub name: String
}
#[derive(Insertable, Debug, AsChangeset)]
#[table_name="products_variants"]
pub struct FormProductVariant {
pub id: Option<i32>,
pub variant_id: Option<i32>,
pub product_id: i32,
pub value: Option<String>
}
pub struct FormProductVariantComplete {
pub variant: Option<FormVariant>,
pub product_variant: FormProductVariant,
}
pub struct FormProduct {
pub product: NewProduct,
pub variants: Vec<FormProductVariantComplete>
}

Next, it’s time for the code to update the product.

Rust 1.40.0
#[macro_use]
extern crate diesel;
use diesel::{SqliteConnection, Connection, QueryDsl, RunQueryDsl};
use anyhow::Result;
use ::shoe_store::models::FormProduct;
no_arg_sql_function!(last_insert_rowid, diesel::sql_types::Integer);
fn update_product(product_id: i32, form_product: FormProduct, conn: &SqliteConnection) -> Result<i32> {
use ::shoe_store::schema::products::dsl::products;
use ::shoe_store::schema::variants;
use ::shoe_store::schema::products_variants::dsl::products_variants;
// We begin a transaction, just to make sure everything runs successfully
conn.transaction(|| {
diesel::update(products.find(product_id))
.set(&form_product.product)
.execute(conn)?;
// We just loop through all variants available
for mut form_product_variant in form_product.variants {
// If there's no variant id, we probably need to insert a new one.
if form_product_variant.product_variant.variant_id.is_none() {
diesel::insert_into(variants::dsl::variants)
.values(form_product_variant.variant)
.execute(conn)?;
let last_variant_id: i32 =
diesel::select(last_insert_rowid).first(conn)?;
form_product_variant.product_variant.variant_id = Some(last_variant_id);
}
// We have an id, so we should update the variant product.
if let Some(product_variant_id) = form_product_variant.product_variant.id {
diesel::update(products_variants.find(product_variant_id))
.set(&form_product_variant.product_variant)
.execute(conn)?;
}
}
Ok(product_id)
})
}

We start updating the ...