如何用Actix Web、Diesel和PostgreSQL按user_id查询subscription表
问题描述
我正在使用Actix Web、Diesel和PostgreSQL开发一个涉及关联表的项目,包含users表与subscription表,当前数据层面无问题。我需要根据user_id列查询subscription表,获取该用户对应的所有相关行,但尚未实现该功能。
相关代码结构
models.rs
#[derive(Queryable, Debug, Associations, Serialize, Deserialize, Insertable)] #[diesel(belongs_to(users::dsl::users, foreign_key = user_id))] #[diesel(table_name = subscriptions)] pub struct Subscription { pub id: Uuid, pub user_id: Uuid, pub name: String, pub updated_at: NaiveDateTime, pub created_at: NaiveDateTime, } #[derive(Queryable, Debug, Serialize, Deserialize)] pub struct User { pub id: Uuid, pub email: Option<String>, pub hashed_password: Option<String>, pub updated_at: Option<NaiveDateTime>, pub created_at: Option<NaiveDateTime>, }
schema.rs
diesel::table! { subscriptions (id) { id -> Uuid, user_id -> Uuid, name -> Varchar, updated_at -> Timestamp, created_at -> Timestamp, } } diesel::table! { users (id) { id -> Uuid, email -> Nullable<Varchar>, hashed_password -> Nullable<Varchar>, updated_at -> Nullable<Timestamp>, created_at -> Nullable<Timestamp>, } } diesel::joinable!(subscriptions -> users (user_id)); diesel::allow_tables_to_appear_in_same_query!( subscriptions, users, );
已实现的基础功能
直接加载所有订阅的功能正常运行:
pub fn fetch_subscriptions( conn: &mut PgConnection, ) -> Result<Vec<Subscription>, diesel::result::Error> { use crate::schema::subscriptions::dsl::*; subscriptions.load::<Subscription>(conn) } pub fn fetch_subscriptions_by_user( conn: &mut PgConnection, uid: Uuid, ) -> Result<Vec<models::Subscription>, diesel::result::Error> { // 需要实现按user_id查询的逻辑 }
请求帮助实现fetch_subscriptions_by_user函数,完成按user_id查询对应subscription数据的功能。
解决方案
你可以通过两种简洁的方式实现该查询功能:
方式一:直接过滤查询
利用Diesel的查询构建器,直接对subscriptions表的user_id字段做条件过滤:
pub fn fetch_subscriptions_by_user( conn: &mut PgConnection, uid: Uuid, ) -> Result<Vec<models::Subscription>, diesel::result::Error> { use crate::schema::subscriptions::dsl::*; use diesel::prelude::*; subscriptions .filter(user_id.eq(uid)) .load::<models::Subscription>(conn) }
该方式生成的SQL等价于SELECT * FROM subscriptions WHERE user_id = $1;,逻辑直接高效。
方式二:利用Diesel的Associations特性
由于你的Subscription结构体已经配置了#[derive(Associations)]和belongs_to注解,可以通过关联关系查询:
pub fn fetch_subscriptions_by_user( conn: &mut PgConnection, uid: Uuid, ) -> Result<Vec<models::Subscription>, diesel::result::Error> { use crate::schema::users::dsl::*; use diesel::prelude::*; use diesel::associations::HasMany; // 先查询用户实例,再获取其关联的订阅列表 let user = users.find(uid).first::<models::User>(conn)?; user.subscriptions(conn) }
这种方式更贴合ORM的关联设计思路,Diesel会自动基于配置的外键生成关联查询逻辑。
注意:两种实现都需要导入diesel::prelude::*来确保所有必要的Query DSL trait可用。
内容的提问来源于stack exchange,提问作者Bhavishya
相关产品推荐
相关产品推荐

