Sequelize hasMany加入关联

Sequelize hasMany Join association

我正在扩展我的应用程序,我需要加入我之前使用 Sequelize 创建的两个模型,它们如下:

吃饭

sequelize.define('meal', {
    mealId: {
        type: DataTypes.INTEGER, 
        primaryKey: true,
        autoIncrement: true
    },
    quantity: {
        type: DataTypes.DECIMAL,
        allowNull: false
    },
    period: {
        type: DataTypes.INTEGER,
        allowNull: false
    }
})

食物

sequelize.define('food', {
    idFood: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    nameFood: {
        type: DataTypes.STRING,
        allowNull: false
    }
})

我添加了以下关系:

db.food.hasMany(db.meal, {as : 'Food', foreignKey : 'idFood'});

此行在 Meal 上添加一个 idFood 列

快速解释一下发生了什么,食物 是一个 table 有很多食物 (duh),如面包、米饭、豆类等 Meal 是一个 table,用于识别用户选择的食物及其详细信息。

因此,我的理解是 Meal 有很多 Food (正如我之前添加的)但是 Food 不需要与 Meal 有任何关系,因为它只保存数据并且在我第一次填充它后不会更改。但是当我试图加入他们时:

db.meal.findAll({ include : [db.food] }).then(function (meals) {
    console.log(JSON.stringify(meals));
});

我收到以下错误:

Unhandled rejection Error: food is not associated to meal!

任何人都可以解释我应该做什么吗?我认为这与关系有关,但我在文档中找不到关于我应该做什么的任何好的解释。

谢谢!

编辑:阅读文档(again),这个例子很有意义,但我不认为这个例子适用于我的情况,因为在他们的例子中,用户有一个任务,任务属于给用户。但就我而言,食物不属于膳食,因为许多膳食可以有不同数量的相同食物(或针对不同用户)。

如果您在关联 ({ as: 'Food' }) 上使用别名,您也需要在 include 语句中使用它。

所以会是这样:

db.meal.findAll({ 
  include : [{
    model: db.food,
    as: 'Food'
  }]
}).then(function (meals) {
  console.log(JSON.stringify(meals));
});

If an association is aliased (using the as option), you must specify this alias when including the model. Notice how the user's Tools are aliased as Instruments above. In order to get that right you have to specify the model you want to load, as well as the alias

更多信息here

问题是关系必须用两种方式定义。目前,Sequelize 知道如何从 Food -> Meal 中获取,因为

db.food.hasMany(db.meal, {as : 'Food', foreignKey : 'idFood'});

但它不知道如何从 Meal -> Food 获取。这就是为什么你必须反过来定义相同的关系,像这样:

db.meal.belongsTo(db.food, {foreignKey : 'idFood'});

这不会添加任何 new 键,因为它会定义您已经在第一条语句中定义的 meal.idFood

现在你应该可以执行了

db.meal.findAll({ include : [db.food] }).then(function (meals) {
    console.log(JSON.stringify(meals)); <-- each array element of meals should have an attribute `food`
});

BelongsTo 还应包含与 hasMany 中具有相同键的外键选项

Donor.hasMany(Donation, {
  foreignKey: "donorId",
  onDelete: "cascade",
});
Donation.belongsTo(Donor, { foreignKey: "donorId" });

这对我有用