域名 AXUM.RS 将于2025年10月到期。我们无意再对其进行续费,我们希望你能够接续这个域名,让更多 AXUM 开发者继续受益。
  • 方案1️⃣AXUM.RS 域名 = 3000
  • 方案2️⃣方案1️⃣ + 本站所有专题原始 Markdown 文档 = 5000
  • 方案3️⃣方案2️⃣ + 本站原始数据库 = 5500
如果你有意接续这份 AXUM 情怀,请与我们取得联系。
说明:
  1. 如果有人购买 AXUM.RS 域名(方案1️⃣),或者该域名到期,本站将启用新的免费域名继续提供服务。
  2. 如果有人购买了 AXUM.RS 域名,且同时购买了内容和/或数据库(方案2️⃣/方案3️⃣),本站将关闭。届时我们或许会以另一种方式与你再相遇。

实现TodoItem

经过一番重构,目前我们的 Todo 服务已经基本完善了,现在只差最后一个部分:TodoItem。本章我们就来实现它。

模型定义

首先,我们在src/model.rs定义相关模型:

/// 待办事项模型
#[derive(PostgresMapper, Serialize)]
#[pg_mapper(table = "todo_item")]
pub struct TodoItem {
    pub id: i32,
    pub title: String,
    pub checked: bool,
    pub list_id: i32,
}

/// 待办事项新ID模型
#[derive(PostgresMapper, Serialize)]
#[pg_mapper(table = "todo_item")]
pub struct TodoItemID {
    pub id: i32,
}

接着,我们在src/form.rs定义相关表单:

#[derive(Deserialize)]
pub struct CreateTodoItem {
    pub title: String,
    pub list_id: i32,
}

数据库操作

然后,我们实现其数据库操作。创建src/db/todo_item.rs文件,并输入以下代码:(别忘了在src/db/mod.rs中声明todo_item模块)

pub async fn all(client: &Client, list_id: i32) -> Result<Vec<TodoItem>> {
    let result: Vec<TodoItem> = super::query(
        client,
        "SELECT id,title,checked,list_id FROM todo_item WHERE list_id=$1 ORDER BY id ASC",
        &[&list_id],
    )
    .await?;
    Ok(result)
}

pub async fn find(client: &Client, list_id: i32, item_id: i32) -> Result<TodoItem> {
    let result: TodoItem = super::query_one(
        client,
        "SELECT id,title,checked,list_id FROM todo_item WHERE id=$1 AND list_id=$2",
        &[&item_id, &list_id],
    )
    .await?;
    Ok(result)
}

pub async fn check(client: &Client, list_id: i32, item_id: i32) -> Result<bool> {
    let result = super::execute(
        client,
        "UPDATE todo_item SET checked=true WHERE id=$1 AND list_id=$2 AND checked=false",
        &[&item_id, &list_id],
    )
    .await?;
    Ok(result > 0)
}

pub async fn delete(client: &Client, list_id: i32, item_id: i32) -> Result<bool> {
    let result = super::execute(
        client,
        "DELETE FROM todo_item WHERE id=$1 AND list_id=$2",
        &[&item_id, &list_id],
    )
    .await?;
    Ok(result > 0)
}

pub async fn create(client: &Client, frm: form::CreateTodoItem) -> Result<TodoItemID> {
    let result = query_one(
        client,
        "INSERT INTO todo_item (title, checked, list_id) VALUES ($1,$2,$3) RETURNING id",
        &[&frm.title, &false, &frm.list_id],
    )
    .await?;
    Ok(result)
}

从代码可以看出,都是对父模块相关方法的调用,这里不再赘述。

handler 的定义

同样的,我们创建src/handler/todo_item.rs,并输入以下内容:

至此,TodoItem 已经开发完成,也意味着整个 Todo 服务开发完成。

要查看完整内容,请先登录