使用 into_boxed() 的柴油中的可选更新语句

optional update statements in diesel using into_boxed()

当我 运行 下面的代码编译时,它不会更新任何 todo 项目并且 affected_rows 等于 0。我在这里做错了什么?

注意:我查了官方documentation,没找到解决办法...

pub fn update_todo(req_id: i32, update_payload: TodoUpdate) -> Result<usize, Error> 
{
    let connection = establish_connection();

    let title_payload = match update_payload.title {
        Some(title_payload)=> title_payload,
        None => "".to_string()
    };

    let status_payload = match update_payload.status {
        Some(status_payload)=> status_payload,
        None => "".to_string()
    };

    let mut query = update(todos)
        .set(id.eq(req_id)).into_boxed();

    if title_payload.len() > 5 {
        query = query.filter(title.eq(title_payload));
    }

    if status_payload.len() > 3 {
        query = query.filter(status.eq(status_payload));
    }

    query.execute(&connection)
}

注意 2:当我不使用 into_boxed() 并删除 if 语句时它工作正常。但如果只有标题长度大于 5 且状态长度大于 3,我想工作。这就是我使用 into_boxed 方法的原因。

我找到了解决方案。我做错了整件事,正确的概念是使用 AsChangeset 来更新数据库中的 rows

任何阅读本文的人:

正确的方法是在你的结构中使用 Optionderive AsChangesettable_name 一起使用,如下例所示:

在此示例中,我们有一个 todo 行,我们只想 change/update 我们 todo 的标题,但不更改状态

#[derive(Serialize, Deserialize, AsChangeset)]
#[table_name="todos"]
pub struct  TodoUpdate {
    pub title: Option<String>,
    pub status: Option<String>
}

现在我们必须修复处理程序并添加验证!我使用 match 语句来检查是否有一个值,如果 title 中有一个值,我检查它的长度,否则我就忽略它。例如:

match update_payload.title {
    Some(ref title_req) => if title_req.len() < 3 {
        return HttpResponse::BadRequest().json(json!({
            "result": false,
            "message": "Title should be at least 3 letter"
        }));
    },
    None => (),
};

match update_payload.status {
    Some(ref status_req) => if status_req.len() < 3 {
        return HttpResponse::BadRequest().json(json!({
            "result": false,
            "message": "Status should be at least 3 letter"
        }));
    },
    None => (),
};

毕竟我调用了我为更新所做的服务todos,它非常简单。

pub fn update_todo(req_id: i32, update_payload: TodoUpdate) -> Result<usize, Error> 
{
    let connection = establish_connection();


    diesel::update(todos.filter(id.eq(req_id)))
        .set::<TodoUpdate>(update_payload)
        .execute(&connection)
}

哇!!!这些代码工作正常..我希望这对你们都有帮助。

PS:如果你真的想验证用户请求数据,你可以使用actix-web-validator