【问题标题】:optional update statements in diesel using into_boxed()使用 into_boxed() 的柴油中的可选更新语句
【发布时间】:2022-12-10 10:10:59
【问题描述】:

当我运行下面的代码时,它会编译但不会更新任何 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 方法的原因。

【问题讨论】:

    标签: rust rust-diesel


    【解决方案1】:

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

    对于任何阅读本文的人:

    正确的方法是在你的结构中使用Option和deriveAsChangeset以及table_name,如下例所示:

    在此示例中,我们有一个 todo 行,我们只想更改/更新我们的 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

    【讨论】:

      猜你喜欢
      • 2020-04-14
      • 2022-12-10
      • 2021-07-06
      • 2022-12-10
      • 2021-08-25
      • 2020-02-06
      • 2020-08-02
      • 2021-03-17
      • 2021-05-08
      相关资源
      最近更新 更多