#[derive(Queryable, Serialize, Identifiable)]
#[has_many(categories)]
pub struct User {
pub id: i32,
pub username: String,
}
#[derive(Queryable, Serialize, Identifiable, Associations)]
#[table_name = "categories"]
#[belongs_to(User, foreign_key = "username")]
pub struct Category {
pub id: i32,
pub username: String,
}
[... later in main.rs ...]
let user: User = users.find(1).first(connection).expect("Error loading user");
let cats = Category::belonging_to(&user).load(connection).expect("Error loading cats");
gives
error[E0599]: no function or associated item named `belonging_to` found for type `models::Category` in the current scope
--> src/main.rs:157:20
|
157 | let cats = Category::belonging_to(&user).load(connection).expect(
| ^^^^^^^^^^^^^^^^^^^^^^
Link two tables using the belonging_to()
Should compile at least.
Regardless of whether these tables have a foreign key relation on DB or not, there's no belonging_to() function to call.
No. Warnings:
warning: unused attribute
--> src/models.rs:8:1
|
8 | #[has_many(categories)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_attributes)] on by default
models.rs as above.
schema.rs (from diesel print-schema):
table! {
users (id) {
id -> Int4,
username -> Varchar,
}
}
table! {
categories (id) {
id -> Int4,
username -> Varchar,
}
}
Please provide your full compiler output
I will send you full project repo in a bit.
Here's the repo: https://github.com/berkus/diesel-belongs-to-bug/blob/master/README.md
steps to reproduce:
(i'm using nightly jfyi)
I reduced your repro case to this minimal case:
#[macro_use] extern crate diesel;
#[macro_use] extern crate diesel_codegen;
use diesel::prelude::*;
table! {
users {
id -> Int4,
username -> Varchar,
}
}
table! {
categories {
id -> Int4,
username -> Varchar,
}
}
#[derive(Identifiable)]
pub struct User {
pub id: i32,
pub username: String,
}
#[derive(Identifiable, Associations)]
#[table_name = "categories"]
#[belongs_to(User, foreign_key = "username")]
pub struct Category {
pub id: i32,
pub username: String,
}
fn main() {
let user = User { id: 1, username: "".into() };
let cats = Category::belonging_to(&user);
}
by switching to UFCS (<Category as BelongingToDsl<&User>>::belonging_to(&user)) we get a much clearer error message:
error[E0277]: the trait bound `diesel::query_builder::SelectStatement<categories::table>: diesel::FilterDsl<diesel::expression::operators::Eq<categories::columns::username, &i32>>` is not satisfied
--> src/main.rs:36:16
|
36 | let cats = <Category as BelongingToDsl<&User>>::belonging_to(&user);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::FilterDsl<diesel::expression::operators::Eq<categories::columns::username, &i32>>` is not implemented for `diesel::query_builder::SelectStatement<categories::table>`
|
= help: the following implementations were found:
<diesel::query_builder::SelectStatement<F, S, D, W, O, L, Of, G> as diesel::FilterDsl<Predicate>>
= note: required because of the requirements on the impl of `diesel::FilterDsl<diesel::expression::operators::Eq<categories::columns::username, &i32>>` for `categories::table`
error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied
--> src/main.rs:36:16
|
36 | let cats = <Category as BelongingToDsl<&User>>::belonging_to(&user);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `i32`
|
= note: required because of the requirements on the impl of `diesel::Expression` for `&i32`
= note: required because of the requirements on the impl of `diesel::expression::AsExpression<diesel::types::Text>` for `&i32`
= note: required because of the requirements on the impl of `diesel::BelongingToDsl<&User>` for `Category`
You are attempting to use the field username as the foreign key, but the primary key of user is id which has the type Integer. You cannot compare an integer and text column.
Thanks!
Most helpful comment
I reduced your repro case to this minimal case:
by switching to UFCS (
<Category as BelongingToDsl<&User>>::belonging_to(&user)) we get a much clearer error message:You are attempting to use the field
usernameas the foreign key, but the primary key ofuserisidwhich has the typeInteger. You cannot compare an integer and text column.