profile of a new registered users
This commit is contained in:
40
src/models/_entities/customer_profiles.rs
Normal file
40
src/models/_entities/customer_profiles.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
//! `SeaORM` Entity for customer shipping/contact profiles. Hand-written to match
|
||||
//! the `customer_profiles` migration (1:1 with `users` via a unique `user_id`).
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "customer_profiles")]
|
||||
pub struct Model {
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
pub updated_at: DateTimeWithTimeZone,
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i32,
|
||||
#[sea_orm(unique)]
|
||||
pub user_id: i32,
|
||||
pub phone_prefix: Option<String>,
|
||||
pub phone: Option<String>,
|
||||
pub address: Option<String>,
|
||||
pub city: Option<String>,
|
||||
pub zip: Option<String>,
|
||||
pub country: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::users::Entity",
|
||||
from = "Column::UserId",
|
||||
to = "super::users::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Users,
|
||||
}
|
||||
|
||||
impl Related<super::users::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Users.def()
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ pub mod prelude;
|
||||
|
||||
pub mod audit_logs;
|
||||
pub mod categories;
|
||||
pub mod customer_profiles;
|
||||
pub mod o_auth2_sessions;
|
||||
pub mod order_items;
|
||||
pub mod orders;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
pub use super::audit_logs::Entity as AuditLogs;
|
||||
pub use super::categories::Entity as Categories;
|
||||
pub use super::customer_profiles::Entity as CustomerProfiles;
|
||||
pub use super::o_auth2_sessions::Entity as OAuth2Sessions;
|
||||
pub use super::order_items::Entity as OrderItems;
|
||||
pub use super::orders::Entity as Orders;
|
||||
|
||||
64
src/models/customer_profiles.rs
Normal file
64
src/models/customer_profiles.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
//! Per-customer shipping/contact profile: the address + phone fields used to
|
||||
//! prefill checkout. One row per user (unique `user_id`); `name`/`email` are
|
||||
//! read from `users`, never duplicated here.
|
||||
|
||||
pub use crate::models::_entities::customer_profiles::{ActiveModel, Column, Entity, Model};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::{ActiveValue, IntoActiveModel, QueryFilter, TryIntoModel};
|
||||
|
||||
pub type CustomerProfiles = Entity;
|
||||
|
||||
/// The editable profile fields, shared by the profile page and the checkout
|
||||
/// "save my address" path.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct ProfileFields {
|
||||
pub phone_prefix: Option<String>,
|
||||
pub phone: Option<String>,
|
||||
pub address: Option<String>,
|
||||
pub city: Option<String>,
|
||||
pub zip: Option<String>,
|
||||
pub country: Option<String>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
async fn before_save<C>(self, _db: &C, _insert: bool) -> std::result::Result<Self, DbErr>
|
||||
where
|
||||
C: ConnectionTrait,
|
||||
{
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Model {
|
||||
/// The profile for `user_id`, if one exists.
|
||||
pub async fn find_for_user(db: &DatabaseConnection, user_id: i32) -> Result<Option<Self>, DbErr> {
|
||||
Entity::find()
|
||||
.filter(Column::UserId.eq(user_id))
|
||||
.one(db)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Insert or update the profile for `user_id` with `fields`, returning the
|
||||
/// persisted row. The unique `user_id` index keeps this 1:1.
|
||||
pub async fn upsert(
|
||||
db: &DatabaseConnection,
|
||||
user_id: i32,
|
||||
fields: ProfileFields,
|
||||
) -> Result<Self, DbErr> {
|
||||
let mut active = match Self::find_for_user(db, user_id).await? {
|
||||
Some(existing) => existing.into_active_model(),
|
||||
None => ActiveModel {
|
||||
user_id: ActiveValue::set(user_id),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
active.phone_prefix = ActiveValue::set(fields.phone_prefix);
|
||||
active.phone = ActiveValue::set(fields.phone);
|
||||
active.address = ActiveValue::set(fields.address);
|
||||
active.city = ActiveValue::set(fields.city);
|
||||
active.zip = ActiveValue::set(fields.zip);
|
||||
active.country = ActiveValue::set(fields.country);
|
||||
active.save(db).await?.try_into_model()
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ pub mod _entities;
|
||||
|
||||
pub mod audit_logs;
|
||||
pub mod categories;
|
||||
pub mod customer_profiles;
|
||||
pub mod o_auth2_sessions;
|
||||
pub mod order_items;
|
||||
pub mod orders;
|
||||
|
||||
Reference in New Issue
Block a user