The trait `diesel::Connection` is not implemented for `DbConnection`

Viewed 1492

I'm trying to add a postgres database to a rocket app using diesel. My main.rs file looks like this, but gives the error "the trait diesel::Connection is not implemented for DbConnection" at .get_result(connection)

#[macro_use] extern crate diesel;
extern crate dotenv;
#[macro_use] extern crate rocket;
#[macro_use] extern crate rocket_contrib;

use diesel::prelude::*;
use rocket_contrib::database;
use rocket_contrib::json::JsonValue;

mod models;
mod schema;

use self::models::*;
use self::schema::*;

#[database("my_db")]
struct DbConnection(diesel::PgConnection);

#[get("/")]
fn index(connection: DbConnection) -> JsonValue {
    json!(all_bicycles(&connection))
}

fn create_bicycle<'a>(connection: &DbConnection, make: &'a str, model: &'a str, rider_type: &'a str, size: &'a str) -> Bicycle {
    let new_bicycle = NewBicycle {
        make,
        model,
        rider_type,
        size
    };

    diesel::insert_into(bicycles::table)
        .values(new_bicycle)
        // the error is on the following line, on `connection`
        .get_result(connection)
        .expect("Error saving bicycle")
}

fn main() {
    rocket::ignite()
        .attach(DbConnection::fairing())
        .mount("/", routes![index])
        .launch();
}

My Cargo.toml (the relevant parts)

[dependencies]
diesel = { version = "1.4.4", features = ["postgres"] }
dotenv = "0.15.0"
rocket = { git = "https://github.com/SergioBenitez/Rocket" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[dependencies.rocket_contrib]
git = "https://github.com/SergioBenitez/Rocket"
default-features = false
features = ["json", "diesel_postgres_pool"]

and my Rocket.toml:

[global.databases]
my_db = { url = "postgres://postgres:@localhost/bikes" }

The error looks like this when expanded:

&DbConnection
the trait bound `DbConnection: diesel::Connection` is not satisfied

the trait `diesel::Connection` is not implemented for `DbConnection`

I've managed to establish the connection to the database, and diesel setup was successful. I'm also able to add migrations - although I think they're unnecessary for this issue.

What am I doing wrong here?

Edit

I worked through the Rocket docs again and realised I was missing the line use rocket_contrib::databases::diesel;, which conflicts with extern crate diesel;, so I moved the database logic into a new module - database.rs. Nothing has really changed, but the new module looks like this:

use rocket_contrib::database;
use rocket_contrib::databases::diesel;

#[database("my_db")]
pub struct DbConnection(diesel::PgConnection);

and it's being used like so:

main.rs

// ...
mod database;
use self::database::DbConnection;
// ...

The error remains the same.

3 Answers

According to the rocket documentation you need to deref your connection type into some type type that implements diesel::connection::Connection as the wrapper type does not implement the necessary trait. So you need to change your code to the following:

    diesel::insert_into(bicycles::table)
        .values(new_bicycle)
        // the error is on the following line, on `connection`
        .get_result(&*connection)
        .expect("Error saving bicycle")

(Note the additional &* before passing the connection into the get_result function.)

I created a StackOverflow account to answer this. I got it working with

connection.run(|conn| {
    diesel::insert_into(bicycles::table)
      .values(new_bicycle)
      .get_result::<Bicycle>(conn)
      .expect("Error saving bicycle")
  }).await;

I have to make the fn async. Also, I am having a Deserialization issue, but I think it's not related.

If I recall it correctly, it should be

#[get("/")]
fn index(connection: DbConnection) -> JsonValue {
    json!(all_bicycles(&*connection))
}

for the route and

fn all_bicycles(connection: &diesel::PgConnection) -> Vec<Bicycle> {
    // ...
    .get_result(connection)
    .expect("Error saving bicycle")
    // ...
}

for your acutal method for querying the database. So, passing the actual diesel connection directly as a reference (since your database abstraction should not necessarily know something about rocket).

Related