You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 10:35:59