Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guide example for connection pools is misleading because it doesn't import diesel's macros #950

Closed
kswope opened this issue Mar 18, 2019 · 9 comments
Assignees
Labels
docs Improvements or additions to documentation

Comments

@kswope
Copy link

kswope commented Mar 18, 2019

https://rocket.rs/v0.4/guide/state/#usage

#[macro_use] extern crate rocket_contrib;

use rocket_contrib::databases::diesel;

#[database("sqlite_logs")]
struct LogsDbConn(diesel::SqliteConnection);

fn main() {
    rocket::ignite()
       .attach(LogsDbConn::fairing())
       .launch();
}

instead of this

use rocket_contrib::databases::diesel;

I had to use this

  + #[macro_use]                                                                                                 
  + extern crate diesel; 

Or none of the diesel macros were available. Resulting in errors like

error: cannot find macro `joinable!` in this scope                                                               
error: cannot find macro `allow_tables_to_appear_in_same_query!` in this scope                                  
error: cannot find macro `table!` in this scope                                                                  
@jebrosen
Copy link
Collaborator

I don't see anything obvious in the documentation about the issue, but it's been discussed a few times on IRC. The re-exports are provided primarily for convenience and a certain amount of version independence -- you can use rocket_contrib::databases::whatever without adding whatever to Cargo.toml or keeping too careful track of which version of whatever is compatible.

This works well for pretty much everything -- except diesel, because diesel depends heavily on its macros and they are pretty much unusable without #[macro_use]. This will be alleviated in diesel-rs/diesel#1956, but it will likely be more convenient to keep using #[macro_use] anyway, at least for a while.

Note that only the crate that uses diesel's macros (e.g. for schema.rs) needs #[macro_use] - if the rocket server is in a separate crate from the database code, the #[macro_use] is unnecessary in the server crate and the example works as-is.


Anyway, I'm not really sure about how best to change the example in question. extern crate diesel; is only needed for diesel so I wouldn't want to add it. On the other hand I think it's just about the most popular way to access databases right now, and it ought to be represented well in the examples.

@jebrosen jebrosen changed the title new connection pool diesel docs seem slightly wrong Guide example for connection pools is misleading because it doesn't import diesel's macros Mar 21, 2019
@kswope
Copy link
Author

kswope commented Mar 21, 2019

and the example works as-is.

I guess that's the root of my issue, the example works, but the example doesn't use diesel, it just puts some diesel connections in a pool.

Maybe be a little merciful to beginners and let them know that to really use diesel you need more than what the example shows?

@simbo1905
Copy link

As a total beginner I would prefer to see examples that immediately get me up and running. A comment in the example that says ”diesel depends heavily on its macros this will be alleviated in diesel-rs/diesel#1956” let's beginners know that it's not the ideal end state.

@flaviut
Copy link

flaviut commented Apr 25, 2019

For anyone else coming here from google, the solution to errors like

error: cannot find macro `table!` in this scope
 --> src/schema.rs:1:1
  |
1 | table! {
  | ^^^^^

error: cannot find macro `joinable!` in this scope
  --> src/schema.rs:98:1
   |
98 | joinable!(EnumValue -> EnumKind (category_id));
   | ^^^^^^^^

error: cannot find macro `allow_tables_to_appear_in_same_query!` in this scope
   --> src/schema.rs:108:1
    |
108 | allow_tables_to_appear_in_same_query!(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: cannot find derive macro `Queryable` in this scope
 --> src/models.rs:1:10
  |
1 | #[derive(Queryable)]
  |          ^^^^^^^^^

or perhaps these errors, which occur when you don't quite understand how rust imports work:

error[E0254]: the name `diesel` is defined multiple times
 --> src/main.rs:7:5
  |
5 | #[macro_use] extern crate diesel;
  |              -------------------- previous import of the extern crate `diesel` here
6 | 
7 | use rocket_contrib::databases::diesel;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `diesel` reimported here
  |
  = note: `diesel` must be defined only once in the type namespace of this module

is to follow the instructions in the top-level bug report.

@jebrosen jebrosen added the docs Improvements or additions to documentation label May 8, 2019
@jebrosen jebrosen self-assigned this May 14, 2019
@kanarok
Copy link

kanarok commented Jul 28, 2019

I case anyone needs some guide... I've found this:
https://cprimozic.net/blog/rust-rocket-cloud-run/

I'm working through it right now.
I stumbled upon the same problems, trying to figure out how to do a simple query.

@jebrosen
Copy link
Collaborator

If I'm reading these right, I think most of the issues with the guide can be addressed by expanding the example to something like this:


[dependencies]
diesel = "1.4"

[dependencies.rocket_contrib]
version = "0.4.2"
default-features = false
features = ["diesel_sqlite_pool", "redis_pool"]
#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate diesel;

// diesel schema
mod schema;
use schema::logs;

// By using redis re-exported from rocket_contrib, we don't need to put redis
// in Cargo.toml and we are guaranteed to use the version of redis that is
// compatible with rocket_contrib.
use rocket_contrib::databases::redis;

#[database("sqlite_logs")]
struct LogsDbConn(diesel::SqliteConnection);

// Multiple databases can be created of the same or different connection types.
#[database("redis_db")]
struct RedisConn(redis::Connection)

#[get("/logs/<id>")]
fn get_logs(conn: LogsDbConn, id: usize) -> diesel::result::QueryResult<Logs> {
    logs::filter(id.eq(log_id)).load(&*conn)
}

#[get("/redis/<id>")]
fn get_redis_value(conn: RedisConn, id: usize) -> Result<String, redis::RedisError> {
    conn.get(id)
}

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

See the todo example for a more complete application, or the rocket_contrib::databases API docs for more details of rocket's database connectivity.

@ghost
Copy link

ghost commented Jun 23, 2021

Again, I agree that this is misleading (as a new Rust developer) especially if you don't know about things such as #[macro_use]. Is there any way for rocket to re-export the macros at least, so I don't end up with two versions of diesel by following the instructions above? (I'm not sure how #[macro_use] works, but I'm sure there is a way even if you have to manually re-export, like for instance pub use Queryable). I understand that the developers have limited time and I would definitely consider contributing myself, but I just don't know where to start really. Also, the linked Diesel issue has been closed.

@SergioBenitez
Copy link
Member

@Hopefulfire There is a complete Rocket example (in examples/databases) for diesel. There's also the todo example.

@SergioBenitez
Copy link
Member

The 0.5 docs now point to multiple fully worked diesel examples. Hopefully this resolves the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

6 participants