Add edit and new for users
This commit is contained in:
parent
57af399ace
commit
cf9a7cf33f
12 changed files with 229 additions and 88 deletions
|
|
@ -23,8 +23,11 @@ pub fn build_app(state: AppState) -> Router {
|
|||
.route("/books/{id}/edit", get(routes::book::edit))
|
||||
.route("/books/new", get(routes::book::new))
|
||||
.route("/users", get(routes::user::index))
|
||||
.route("/users/new", get(routes::user::new))
|
||||
.route("/users/{id}/edit", get(routes::user::edit))
|
||||
.route("/users/{id}", post(routes::user::update))
|
||||
.route("/users", post(routes::user::create))
|
||||
.route("/users/{id}", post(routes::user::delete))
|
||||
.route("/users/{id}/delete", post(routes::user::delete))
|
||||
.nest("/assets", static_router())
|
||||
.with_state(state)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ impl BookOperator {
|
|||
let book_pages = Entity::find()
|
||||
.filter(conditions)
|
||||
.order_by_desc(Column::Id)
|
||||
.paginate(&self.state.db, 1);
|
||||
.paginate(&self.state.db, 100);
|
||||
|
||||
let books = book_pages
|
||||
.fetch_page(page_0indexed)
|
||||
|
|
@ -140,6 +140,15 @@ impl BookOperator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Finds vec of book by its Owner
|
||||
pub async fn find_all_by_owner(&self, owner_id: i32) -> Result<Vec<Model>, BookError> {
|
||||
Entity::find()
|
||||
.filter(Column::OwnerId.eq(owner_id))
|
||||
.all(&self.state.db)
|
||||
.await
|
||||
.context(DBSnafu)
|
||||
}
|
||||
|
||||
/// Creates a new book from the given form data.
|
||||
pub async fn create(&self, form: BookForm) -> Result<Model, BookError> {
|
||||
let book = ActiveModel {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use crate::models::book::BookOperator;
|
||||
use crate::routes::user::UserForm;
|
||||
use crate::state::AppState;
|
||||
use crate::state::error::UserSnafu;
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use sea_orm::DeleteResult;
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
|
@ -74,6 +76,20 @@ impl UserOperator {
|
|||
user.insert(&self.state.db).await.context(DBSnafu)
|
||||
}
|
||||
|
||||
pub async fn update(&self, id: i32, form: UserForm) -> Result<Model, UserError> {
|
||||
let user_by_id = Self::find_by_id(&self, id).await.context(UserSnafu);
|
||||
|
||||
if let Ok(user) = user_by_id {
|
||||
let mut user: ActiveModel = user.into();
|
||||
|
||||
user.name = Set(form.name);
|
||||
|
||||
user.update(&self.state.db).await.context(DBSnafu)
|
||||
} else {
|
||||
Err(UserError::NotFound { id })
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete(&self, user_id: i32) -> Result<DeleteResult, UserError> {
|
||||
let user: Option<Model> = Entity::find_by_id(user_id)
|
||||
.one(&self.state.db)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,16 @@ use crate::{
|
|||
#[derive(Template, WebTemplate)]
|
||||
#[template(path = "users/index.html")]
|
||||
struct UsersIndexTemplate {
|
||||
user_with_books_number: Vec<(user::Model, usize, usize)>,
|
||||
user_with_books_number: Vec<UserWithBookNumber>,
|
||||
}
|
||||
|
||||
pub struct UserWithBookNumber {
|
||||
/// the user model
|
||||
pub user: user::Model,
|
||||
/// the number of books owned by this user
|
||||
pub owner_book_number: usize,
|
||||
/// the number of books borrowed by this user
|
||||
pub borrowed_book_number: usize,
|
||||
}
|
||||
|
||||
pub async fn index(
|
||||
|
|
@ -40,7 +49,7 @@ pub async fn index(
|
|||
.await
|
||||
.context(BookSnafu)?;
|
||||
|
||||
let mut result: Vec<(user::Model, usize, usize)> = vec![];
|
||||
let mut result: Vec<UserWithBookNumber> = Vec::with_capacity(users.len());
|
||||
|
||||
let mut owner_books: HashMap<i32, usize> = HashMap::new();
|
||||
let mut borrowed_books: HashMap<i32, usize> = HashMap::new();
|
||||
|
|
@ -56,7 +65,11 @@ pub async fn index(
|
|||
let owner_books_size = owner_books.get(&user.id).unwrap_or(&0);
|
||||
let borrowed_books_size = borrowed_books.get(&user.id).unwrap_or(&0);
|
||||
|
||||
result.push((user, *owner_books_size, *borrowed_books_size));
|
||||
result.push(UserWithBookNumber {
|
||||
user,
|
||||
owner_book_number: *owner_books_size,
|
||||
borrowed_book_number: *borrowed_books_size,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(UsersIndexTemplate {
|
||||
|
|
@ -73,7 +86,7 @@ pub async fn create(
|
|||
State(state): State<AppState>,
|
||||
Form(form): Form<UserForm>,
|
||||
) -> Result<impl axum::response::IntoResponse, AppStateError> {
|
||||
let _user = UserOperator::new(state)
|
||||
let _ = UserOperator::new(state)
|
||||
.create(form)
|
||||
.await
|
||||
.context(UserSnafu)?;
|
||||
|
|
@ -81,6 +94,19 @@ pub async fn create(
|
|||
Ok(Redirect::to("/users"))
|
||||
}
|
||||
|
||||
pub async fn update(
|
||||
State(state): State<AppState>,
|
||||
Path(id): Path<i32>,
|
||||
Form(form): Form<UserForm>,
|
||||
) -> Result<impl axum::response::IntoResponse, AppStateError> {
|
||||
let _ = UserOperator::new(state)
|
||||
.update(id, form)
|
||||
.await
|
||||
.context(UserSnafu)?;
|
||||
|
||||
Ok(Redirect::to("/users"))
|
||||
}
|
||||
|
||||
pub async fn delete(
|
||||
State(state): State<AppState>,
|
||||
Path(id): Path<i32>,
|
||||
|
|
@ -92,3 +118,29 @@ pub async fn delete(
|
|||
|
||||
Ok(Redirect::to("/users"))
|
||||
}
|
||||
|
||||
#[derive(Template, WebTemplate)]
|
||||
#[template(path = "users/edit.html")]
|
||||
struct EditTemplate {
|
||||
user: user::Model,
|
||||
}
|
||||
|
||||
pub async fn edit(
|
||||
State(state): State<AppState>,
|
||||
Path(id): Path<i32>,
|
||||
) -> Result<impl axum::response::IntoResponse, AppStateError> {
|
||||
let user = UserOperator::new(state)
|
||||
.find_by_id(id)
|
||||
.await
|
||||
.context(UserSnafu)?;
|
||||
|
||||
Ok(EditTemplate { user })
|
||||
}
|
||||
|
||||
#[derive(Template, WebTemplate)]
|
||||
#[template(path = "users/new.html")]
|
||||
struct NewTemplate {}
|
||||
|
||||
pub async fn new() -> impl axum::response::IntoResponse {
|
||||
NewTemplate {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue