Nikolai Savulkin
Nikolai Savulkin

Reputation: 759

Diesel derive Insertable causes ambiguous associated type error

So I'm trying to build a rust powered API closely following this tutorial. My models.rs looks like this:

use diesel;
use diesel::prelude::*;
use diesel::sqlite::SqliteConnection as slc;


use crate::schema::{Recipe as RecipeTable,
                    RecipeMatchIngredient as RecipeMatchIngredientTable,
                    AllergyMatchIngredient as AllergyMatchIngredientTable,
                    DietMatchIngredient as DietMatchIngredientTable,
                    Ingredient as IngredientTable};

use crate::schema::{
    Recipe::dsl::Recipe as AllRecipe,
    RecipeMatchIngredient::dsl::RecipeMatchIngredient as AllRecipeMatchIngredient,
    AllergyMatchIngredient::dsl::AllergyMatchIngredient as AllAllergyMatchIngredient,
    DietMatchIngredient::dsl::DietMatchIngredient as AllDietMatchIngredient,
    Ingredient::dsl::Ingredient as AllIngredient
};



#[derive(Queryable)]
pub struct Recipe {
    pub id: u64,
    pub associated_author_id: u64,
    pub meal_type: String,
    pub cuisine: String,
    pub estimated_ttc: u64,
    pub difficulty: u64,
    pub count_upvotes: u64,
    pub count_reports: u64,
}

impl Recipe {

}

#[derive(Insertable)]
#[table_name="Recipe"]
pub struct NewRecipe {
    pub associated_author_id: u64,
    pub meal_type: String,
    pub cuisine: String,
    pub estimated_ttc: u64,
    pub difficulty: u64,
    pub count_upvotes: u64,
    pub count_reports: u64,
}

//==================================================================================================

#[derive(Queryable)]
pub struct Ingredient {
    pub id: u64,
    pub name: String,
    pub cost_eur_cents: u64,
    pub calories: u64,
}


#[derive(Insertable)]
#[table_name="Ingredient"]
pub struct NewIngredient {
    pub name: String,
    pub cost_eur_cents: u64,
    pub calories: u64,
}

//==================================================================================================

#[derive(Queryable)]
pub struct RecipeMatchIngredient {
    pub link_id: u64, // diesel enforces to have primary key
    pub recipe_id: u64,
    pub ingredient_id: u64
}


#[derive(Insertable)]
#[table_name="RecipeMatchIngredient"]
pub struct NewRecipeMatchIngredient {
    pub recipe_id: u64,
    pub ingredient_id: u64
}

//==================================================================================================

#[derive(Queryable)]
pub struct AllergyMatchIngredient {
    pub link_id: u64, // diesel enforces to have primary key
    pub allergy: String,
    pub ingredient_id: u64
}


#[derive(Insertable)]
#[table_name="AllergyMatchIngredient"]
pub struct NewAllergyMatchIngredient {
    pub allergy: String,
    pub ingredient_id: u64
}

//==================================================================================================

#[derive(Queryable)]
pub struct DietMatchIngredient {
    pub link_id: u64, // diesel enforces to have primary key
    pub diet: String,
    pub ingredient_id: u64,
}


#[derive(Insertable)]
#[table_name="DietMatchIngredient"]
pub struct NewDietMatchIngredient {
    pub diet: String,
    pub ingredient_id: u64,
}

and my up.sql is like this:

-- Your SQL goes here
CREATE TABLE Recipe (
    id INTEGER PRIMARY KEY NOT NULL,
    associated_user_id INTEGER NOT NULL,
    meal_type VARCHAR NOT NULL,
    cuisine VARCHAR NOT NULL,
    estimated_ttc INTEGER NOT NULL,
    difficulty INTEGER NOT NULL,
    count_upvotes INTEGER NOT NULL,
    count_reports INTEGER NOT NULL
);


CREATE TABLE Ingredient (
    id INTEGER PRIMARY KEY NOT NULL,
    name VARCHAR NOT NULL,
    cost_eur_cents INTEGER NOT NULL,
    calories INTEGER NOT NULL
);


CREATE TABLE RecipeMatchIngredient (
    link_id INTEGER PRIMARY KEY NOT NULL,
    recipe_id INTEGER NOT NULL,
    ingredient_id INTEGER NOT NULL,
    FOREIGN KEY(ingredient_id) REFERENCES Ingredient(id),
    FOREIGN KEY(recipe_id) REFERENCES Recipe(id)
);


CREATE TABLE AllergyMatchIngredient (
    link_id INTEGER PRIMARY KEY NOT NULL,
    allergy VARCHAR NOT NULL,
    ingredient_id INTEGER NOT NULL,
    FOREIGN KEY(ingredient_id) REFERENCES Ingredient(id)
);


CREATE TABLE DietMatchIngredient (
    link_id INTEGER PRIMARY KEY NOT NULL,
    diet VARCHAR NOT NULL,
    ingredient_id INTEGER NOT NULL,
    FOREIGN KEY(ingredient_id) REFERENCES Ingredient(id)
);

However it produces following error:

error[E0223]: ambiguous associated type
  --> src\models.rs:38:10
   |
38 | #[derive(Insertable)]
   |          ^^^^^^^^^^ help: use fully-qualified syntax: `<models::Recipe as Trait>::table`
   |
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

I thought that perhaps the error implies something shadows the items in #[table_name=] macro, but quick test with a new database schema didn't give any results.

Upvotes: 2

Views: 800

Answers (1)

weiznich
weiznich

Reputation: 3445

The correct variant would be the use the table module comming from your schema.rs file. According to your imports that would result in the following adjusted struct definition:

#[derive(Insertable)]
#[table_name="RecipeTable"]
pub struct NewRecipe {
    pub associated_author_id: u64,
    pub meal_type: String,
    pub cuisine: String,
    pub estimated_ttc: u64,
    pub difficulty: u64,
    pub count_upvotes: u64,
    pub count_reports: u64,
}

Checkout the "All about inserts" guide for more details about how inserts are work using diesel.

Upvotes: 1

Related Questions