最近我在sequelize文档中发现this,您可以使用include创建。现在我尝试在我的程序上执行它,但只创建“父”模型的记录而不是子项。
这是我的模特和我的控制器。
var MainMenu = sequelize.define('MainMenu', {
Name: {
type: DataTypes.STRING(50)
},
Day: {
type: DataTypes.DATE
},
RecordStatus:{
type: DataTypes.BOOLEAN,
defaultValue: true
},
DeletedAt: {
type: DataTypes.DATE
}
},
{
associate: function(models){
models.MainMenu.hasMany(models.MainMeal, {as: 'Menu'});
}
}
);
exports.createIn = (req, res) => {
let Menu = {
Name: 'MenuTest',
MainMeal: [{
Type: 'Breakfast',
Name: 'MealTest1'
}, {
Type: 'Lunch',
Name: 'MealTest2'
}]
};
db.MainMenu.create(Menu, {
include: [{
model: db.MainMeal,
as: 'Menu'
}]
})
.then( mainmenu => {
if (!mainmenu) {
return res.send('users/signup', {
errors: 'Error al registrar el mainmenu.'
});
} else {
return res.jsonp(mainmenu);
}
})
.catch( err => {
console.log(err);
return res.status(400)
.send({
message: errorHandler.getErrorMessage(err)
});
});
};
在我的情况下,它只创建MainMenu
记录,而不是MainMeal
记录。我做错了什么?
答案 0 :(得分:2)
更改您的menu
对象,并添加Menu
数组,而不是MainMeal
- 您必须在对象
中提供别名
let mainMenu = {
Name: 'MenuTest',
Menu: [{
Type: 'Breakfast',
Name: 'MealTest1'
}, {
Type: 'Lunch',
Name: 'MealTest2'
}]
};
现在,
db.MainMenu.create(mainMenu, {
include: [{
model: db.MainMeal,
as: 'Menu'
}]
})
.then( mainmenu => {
if (!mainmenu) {
return res.send('users/signup', {
errors: 'Error al registrar el mainmenu.'
});
} else {
return res.jsonp(mainmenu);
}
})
.catch( err => {
console.log(err);
return res.status(400)
.send({
message: errorHandler.getErrorMessage(err)
});
});
答案 1 :(得分:1)
主要的事情当然是Menu
的命名应该是传递给.create()
本身的数据,以及那里提供的参数和如果你真的需要指定别名“两次”,您不需要。但还有其他一些事情需要注意。
我个人更喜欢将关联存储为自己的导出,并将其包含在语句中。当您稍后了解该关联的用法时,这通常会变得更加清晰。
我还强烈建议您在跨多个表“编写”内容时,然后实施transactions以确保实际创建所有相关项目,并且在出现任何错误时不会将其孤立。
作为基于示例的简要列表:
const Sequelize = require('sequelize');
const sequelize = new Sequelize('sqlite:menu.db',{ logging: console.log });
const MainMeal = sequelize.define('MainMeal', {
Type: { type: Sequelize.STRING(50) },
Name: { type: Sequelize.STRING(50) }
});
const MainMenu = sequelize.define('MainMenu', {
Name: { type: Sequelize.STRING(50) }
});
MainMenu.Meals = MainMenu.hasMany(MainMeal, { as: 'Menu' });
(async function() {
try {
await sequelize.authenticate();
await MainMeal.sync({ force: true });
await MainMenu.sync({ force: true });
let result = await sequelize.transaction(transaction =>
MainMenu.create({
Name: 'MenuTest',
Menu: [
{ Type: 'Breakfast', Name: 'MealTest1' },
{ Type: 'Lunch', Name: 'MealTest2' }
]
},{
include: MainMenu.Meals,
transaction
})
);
} catch(e) {
console.error(e);
} finally {
process.exit();
}
})();
会输出类似的内容:
Executing (default): SELECT 1+1 AS result
Executing (default): DROP TABLE IF EXISTS `MainMeals`;
Executing (default): CREATE TABLE IF NOT EXISTS `MainMeals` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `Type` VARCHAR(50), `Name` VARCHAR(50), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `MainMenuId` INTEGER REFERENCES `MainMenus` (`id`) ON DELETE
SET NULL ON UPDATE CASCADE);
Executing (default): PRAGMA INDEX_LIST(`MainMeals`)
Executing (default): DROP TABLE IF EXISTS `MainMenus`;
Executing (default): CREATE TABLE IF NOT EXISTS `MainMenus` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `Name` VARCHAR(50), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`MainMenus`)
Executing (3d645847-56ca-435a-b786-6be62a05e8d5): BEGIN DEFERRED TRANSACTION;
Executing (3d645847-56ca-435a-b786-6be62a05e8d5): INSERT INTO `MainMenus` (`id`,`Name`,`createdAt`,`updatedAt`) VALUES (NULL,'MenuTest','2018-04-14 08:08:17.132 +00:00','2018-04-14 08:08:17.132 +00:00');
Executing (3d645847-56ca-435a-b786-6be62a05e8d5): INSERT INTO `MainMeals` (`id`,`Type`,`Name`,`createdAt`,`updatedAt`,`MainMenuId`)
VALUES (NULL,'Breakfast','MealTest1','2018-04-14 08:08:17.152 +00:00','2018-04-14 08:08:17.152 +00:00',1);
Executing (3d645847-56ca-435a-b786-6be62a05e8d5): INSERT INTO `MainMeals` (`id`,`Type`,`Name`,`createdAt`,`updatedAt`,`MainMenuId`)
VALUES (NULL,'Lunch','MealTest2','2018-04-14 08:08:17.153 +00:00','2018-04-14 08:08:17.153 +00:00',1);
Executing (3d645847-56ca-435a-b786-6be62a05e8d5): COMMIT;
创建数据时,事务BEGIN
和COMMIT
包含所有这些INSERT
语句的重要部分。即使没有实现交易,您仍然会看到两个项目与相关的“父”一起创建。但问题的关键在于,这是“应该”实施交易的地方。
另请注意,数据创建和后续访问中使用的"aliased" Menu
实际上并非“必须”包含在{{1}的.create()
方法中}} 选项。它是“可选的”,并且已在include
参数下定义,因此您不需要再次执行此操作。
即使您这样做了,那么该部分仍然是与.hasMany()
参数一起使用的“关联”:
model
因此,不要将被引用的“表格”的模型的原始名称混淆,这也可能是另一个混淆点。