使用 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
;
任何阅读本文的人:
正确的方法是在你的结构中使用 Option
和 derive
AsChangeset
与 table_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
当我 运行 下面的代码编译时,它不会更新任何 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
;
任何阅读本文的人:
正确的方法是在你的结构中使用 Option
和 derive
AsChangeset
与 table_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