How do I insert into a many-to-many join table using Diesel?

How do I insert into a many-to-many join table using Diesel?

The two tables:

table! {
    candidate_accounts (id) {
        id -> Int8,
        email_address -> Varchar,
        password -> Varchar,
    }
}

table! {
    jobs (id) {
        id -> Int8,
        title -> Varchar,
        description -> Nullable<Varchar>,
    }
}

The many-to-many table:

table! {
    applications (id) {
        id -> Int8,
        candidate_account_id -> Int8,
        job_id -> Int8,
    }
}

joinable!(applications -> candidate_accounts (candidate_account_id));
joinable!(applications -> jobs (job_id));

and my method:

pub fn apply_job(candidate_account_id: i64, job_id: i64) {
    use schema::applications::dsl::*;
    let db_conn = database::POOL.get().unwrap();
    diesel::insert_into(applications).values((
        candidate_account_id.eq(candidate_account_id),
        job_id.eq(job_id)
    )).execute(&db_conn);
}

And I get this error

|        ^^^^^^^ expected struct `diesel::query_source::Never`, found struct `diesel::query_source::Once`

I'm using Rust 1.37 and Diesel 1.4.2.

Thanks!

OK. I managed to get it to compile by changing to:

Adding "Associations" to #[derive ... for

  • Job
  • CandidateAccount

and:

use super::schema::applications;

#[derive(Identifiable, Associations, Insertable, Queryable, Serialize, Deserialize)]
#[table_name="applications"]
#[belongs_to(CandidateAccount)]
#[belongs_to(Job)]
pub struct Application {
    pub id: i64,
    pub candidate_account_id: i64,
    pub job_id: i64,
}

The code:

pub fn apply_job(the_candidate_account_id: i64, the_job_id: i64) {
    use schema::applications::dsl::*;
    use schema::candidate_accounts::dsl::*;
    let db_conn = database::POOL.get().unwrap();
    let job_application = models::Application {
        id: 0, // PROBLEM #1
        candidate_account_id: the_candidate_account_id, // PROBLEM #2
        job_id: the_job_id // PROBLEM #2
    };
    diesel::insert_into(applications).values(&job_application).execute(&db_conn);
}

There are 2 problems, as highlighted in the code.

PROBLEM #1
How to I remove the "id: 0". The database should fill an incremented value automatically.

PROBLEM #2
I thought there is a shorthand to simply put:

candidate_account_id

instead of (repeating and I have to use a different name in the parameter by adding "the_" prefix:

candidate_account_id: the_candidate_account_id

Thanks!

OK. This:

pub fn apply_job(the_candidate_account_id: i64, the_job_id: i64) {
    use schema::applications::dsl::*;
    let db_conn = database::POOL.get().unwrap();
    diesel::insert_into(applications).values((
        candidate_account_id.eq(the_candidate_account_id),
        job_id.eq(the_job_id)
    )).execute(&db_conn);
}

I got it to compile. (Still, it is not yet tested).