Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"use of undeclared type or module" when using Diesel's `belongs_to` attribute

I'm loosely following Diesel's getting started guide trying to set up a relational database, but getting the following error on compile:

error[E0433]: failed to resolve: use of undeclared type or module `birds`
 --> src/models.rs:9:12
  |
9 | pub struct Bird {
  |            ^^^^ use of undeclared type or module `birds`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0433`.
error: Could not compile `prrr_gql`.

Here's the binary:

extern crate prrr_gql;
extern crate diesel;

use self::prrr_gql::*;
use self::models::*;
use self::diesel::prelude::*;

fn main() {
    use prrr_gql::schema::cats::dsl::*;
    use prrr_gql::schema::birds::dsl::*;

    let connection = establish_connection();
    let results = cats.load::<Cat>(&connection)
        .expect("Error hearding cats");

    for cat in results {
        println!("{}", cat.name);
    }
}

and lib.rs (imported as prrr_gql)

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

use diesel::prelude::*;
use diesel::pg::PgConnection;
use dotenv::dotenv;
use std::env;

pub mod schema;
pub mod models;

pub fn establish_connection() -> PgConnection {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL")
        .expect("DATABASE_URL must be set");

    PgConnection::establish(&database_url)
        .expect(&format!("Error connecting to {}", database_url))
}

models.rs

#[derive(Queryable, Debug)]
pub struct Cat {
    pub id: i32,
    pub name: String,
}

#[derive(Queryable, Associations, Debug)]
#[belongs_to(Cat)]
pub struct Bird {
    pub id: i32,
    pub cat_id: i32,
    pub species: String,
    pub colors: String
}

and the schema.rs generated by Diesel

table! {
    birds (id) {
        id -> Int4,
        species -> Varchar,
        colors -> Varchar,
        cat_id -> Nullable<Int4>,
    }
}

table! {
    cats (id) {
        id -> Int4,
        name -> Varchar,
    }
}

joinable!(birds -> cats (cat_id));

allow_tables_to_appear_in_same_query!(
    birds,
    cats,
);

The only issue I could find related to this says I need to have birds in scope and references the table! macro that I have provided, so I'm not sure what's missing.

When I comment out everything related to the birds database, everything runs as expected.

Full project with Cargo.toml for reference: https://github.com/crashspringfield/prrr_gql/tree/diesel-error

like image 826
crash springfield Avatar asked Jul 02 '19 12:07

crash springfield


People also ask

How do I use a diesel expression with a user interface?

A DIESEL expression can be used with a user interface element and must follow the $section=submenu format; where the section name is M and the submenu is the DIESEL expression you want. This DIESEL expression provides a way to toggle between model space and paper space based on the current value of the CVPORT system variable.

What is wrong with the design of diesel?

This design leads to many problems, including N+1 query bugs, and runtime errors when accessing an association that isn’t there. In Diesel, data and its associations are considered to be separate. If you want to pass around a user and all of its posts, that type is (User, Vec<Post>).

How do I declare an association between two records in diesel?

You can declare an association between two records with # [belongs_to] . Unlike other ORMs, Diesel has no concept of # [has_many] Note that in addition to the # [belongs_to] annotation, we also need to # [derive (Associations)] # [belongs_to] is given the name of the struct that represents the parent.

How to pass data from one user to another in diesel?

In Diesel, data and its associations are considered to be separate. If you want to pass around a user and all of its posts, that type is (User, Vec<Post>). Next lets look at how to load the children for more than one parent record. [ belonging_to ] [belonging-to] can be used to load the data, but we’ll also need to group it with its parents.


1 Answers

As the error mentions, birds is not in scope. The table! macro creates a public module (birds), which you then need to bring into scope to be able to derive Associations (in models.rs):

use super::schema::birds;

See diesel::associations for an example, where it shows that one needs to use the schema for derive.

like image 163
ocstl Avatar answered Oct 19 '22 18:10

ocstl