Want diesel update to fail if not found

How can I make the update_name method here produce an error if no record with a matching id is found?

I believe execute returns the number of rows updated, so you could do something like this:

let count = diesel::update(/* ... */).execute(conn)?;
if count == 0 {
    return Err(Error::NotFound);
}
1 Like

Thanks! That got me to a solution. It looks like I have to do this:

fn update_name(conn: &PgConnection, id: i32, name: &str) -> Result<usize, Error> {
    let dog = schema::dogs::dsl::dogs.filter(schema::dogs::id.eq(id));
    let result = diesel::update(dog)
        .set(schema::dogs::name.eq(name))
        .execute(conn);
    if let Ok(count) = result {
        if count == 0 {
            return Err(Error::NotFound);
        }
    }
    result
}

You should be able to use if result == Ok(0) { here to directly compare the value inside the Option.

2 Likes

Nice! I didn't realize that would work. I thought it would treat Ok(0) like it was an object at a different address than result and not compare the same.

That actually happens rarely in Rust. There is no default by-address comparison in the language. Instead, equality is defined via the Eq and PartialEq traits (for which == is syntactic sugar).

The normal way to implement the traits is by recursive by-value comparisons. This is what you get when you add #[derive(Eq, PartialEq)] on a strict and the stdlib implements equality the same way for common types like Option, Result, etc.

1 Like