【发布时间】:2019-09-17 15:59:06
【问题描述】:
我在我的 Node.js 应用程序中使用 Sequelize.js 并一直遇到一个非常奇怪的问题。
背景:我有两个模型,Account和AccountCategory如下。我的 API 端点调用路由 /accounts,它调用帐户控制器来执行 Account.findAll() 查询。
Accounts 模型有一个 defaultScope 以默认包含相关类别,而不必每次都在 findAll({}) 块内指定它。
问题:当 Accounts 模型试图访问并返回数据库中的数据时,defaultScope 试图包含 AccountCategory em>,Sequelize 报错:
包括意外。元素必须是模型、关联或对象。
我怀疑这与设置模型时 AccountCategory 放在我的 models 文件夹中的 Account 之后的事实有关因此未处理(关联)。我基于这样一个事实,即 User 和 Role 等其他关联(即用户具有角色)使用相同的方法很好(即路径深度没有问题正如this answer 建议的那样)。
过去 2 天我一直在尝试让 defaultScope 正常工作并停止产生此错误,但没有任何运气。类似的问题没有提供答案,我将非常感谢解决此问题的任何帮助。谢谢。
帐号:
module.exports = (sequelize, DataTypes) => {
const Account = sequelize.define(
"Account",
{
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(100)
},
category_id: {
type: DataTypes.INTEGER(11),
allowNull: false
}
},
{
timestamps: false,
tableName: "Account",
defaultScope: {
include: [{
model: sequelize.models.AccountCategory,
as: "category"
}]
}
}
);
Account.associate = models => {
// Association: Account -> AccountCategory
Account.belongsTo(models.AccountCategory, {
onDelete: "CASCADE",
foreignKey: {
fieldName: "category_id",
allowNull: false,
require: true
},
targetKey: "id",
as: "category"
});
};
return Account;
};
帐户类别:
module.exports = (sequelize, DataTypes) => {
var AccountCategory = sequelize.define(
"AccountCategory",
{
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(30),
allowNull: false,
unique: true
}
},
{
timestamps: false,
tableName: "Account_Category"
}
);
return AccountCategory;
};
型号索引:
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || "development";
const db = {};
const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASS,
{
host: process.env.DB_HOST,
dialect: "mysql",
operatorAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
}
);
fs.readdirSync(__dirname)
.filter(function(file) {
return (
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
);
})
.forEach(function(file) {
var model = sequelize["import"](path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if (db[modelName].associate) {
db[modelName].associate(db);
}
db[modelName].associate(db);
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
【问题讨论】:
-
你确定你的代码顺序吗? IE。应该是 define() 语句,然后是 associate(),然后是 findAll()?类似的代码对我有用...
-
我是,您能否尝试重命名您尝试包含的模型,使其出现在引用它的模型之前?只是想证实我的怀疑。
-
尝试这样做对我来说很痛苦。你不能自己做吗,例如将 readDir 替换为
var model = sequelize["import"](path.join(__dirname, 'account.js')); db[model.name] = model;model = sequelize["import"](path.join(__dirname, 'account_categoryjs')); db[model.name] = model;(或者,您想要的任何顺序?)
标签: mysql node.js sequelize.js associations