rustactix-webrust-diesel

Querying a joined table with Actix Web, Diesel and PostGresQL


I am using Actix web, Diesel and PostGresQL for a project which involves a few joined databases. There's one users table and one subscription table. Data at this point is not a part of the problem that should be considered.

I want to query my subscription table on the basis of the user_id column and get all related rows back from the db which I have failed to do so far.

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,
);

I have tried directly loading the table works fine so that doesn't seem to be the problem.

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> {

    // working code here
}

Solution

  • You can use the dsl of subscriptions to test for equality of the user_id UUID:

    use uuid::Uuid;
    
    pub fn fetch_subscriptions_by_user(
        conn: &mut PgConnection,
        uid: Uuid,
    ) -> Result<Vec<models::Subscription>, diesel::result::Error> {
        use crate::schema::subscriptions::dsl::*;
        subscriptions.filter(user_id.eq(uid)).load::<models::Subscription>(conn)
    }