从 Sequelize getter 方法访问关联的 table
Accessing an associated table from a Sequelize getter method
这是我使用 C++ 20 年后的第一个 node.js 网络应用程序,我想我只是需要有人在这里为我指明正确的方向。
我正在编写一个与学校和学生打交道的应用程序的服务器端。当客户端为特定学生发送请求(通过我的 REST API)时,我想 return 学生的姓名和学校。我正在使用一个名为 epilogue 的库来解析请求,通过 sequelize reads/writes 到 MySQL 数据库,并将结果包装在 JSON 响应中。它将发送我为学生定义的所有字段以及我定义的任何 getter 的值。一切都很好。我已经能够使用尾声 POST、PUT、GET 并通常保持 MySQL 数据库更新。
但是,当我尝试定义 return 学生学校名称的 getter 方法时,事情变得棘手了。为此,我必须访问学校 table 中的记录并获取学校名称。
var school = sequelize.define("School", {
SchoolName: {
type: DataTypes.STRING,
},
}, {
classMethods: {
associate: function(models) {
school.hasMany(models.Student);
}
}
}
}
var student = sequelize.define("Student", {
FirstName: {
type: DataTypes.STRING,
},
LastName: {
type: DataTypes.STRING,
},
}, {
classMethods: {
associate: function(models) {
student.belongsTo(models.School);
},
},
getterMethods: {
FullName: function() {
return this.FirstName + ' ' + this.LastName; // This works just fine
},
SchoolName: function() {
return this.getSchool().SchoolName; // This doesn't work because getSchool is asynchronous
}
}
}
}
问题是 .getSchool() 是异步的,所以我似乎必须使用 .then 来访问结果。承诺对我来说是一个新概念,但我尝试过类似的事情:
SchoolName: function {
return this.getSchool.then(function(school) {
return school.SchoolName;
});
}
但这似乎只是 return 承诺本身,而不是承诺的结果,因为承诺在 getter return 时并未实现。所以,我最终向客户发送了类似的内容:
{
"FullName": "John Doe",
"SchoolName": {
"isFulfilled": false,
"isRejected": false
},
"id":1,
"FirstName":"John",
"LastName":"Doe"
}
这里的 getter 似乎必须是同步的,所以看起来我只需要一些方法来告诉 getter 停止并等待 Promise 完成然后 return 值。但这似乎违反了 node.js 的异步性质。所以,我有一种预感,我从根本上误解了一些关于 sequelize.js 或 node.js 或承诺甚至数据库设计的重要内容。有人可以重定向我吗?主要是,我想知道:正确的方法是什么?
是的,getSchool()
方法 returns 一个承诺。您需要让 sequelize 查询包含关联。您可以通过创建一个新的网络服务并放入您自己的 sequelize 查询来手动执行此操作,或者如果可以的话告诉 epilogue 执行此操作。看一个unit test in the epilogue code。也许您可以添加选项:associations: true
以加载关联。
这是我使用 C++ 20 年后的第一个 node.js 网络应用程序,我想我只是需要有人在这里为我指明正确的方向。
我正在编写一个与学校和学生打交道的应用程序的服务器端。当客户端为特定学生发送请求(通过我的 REST API)时,我想 return 学生的姓名和学校。我正在使用一个名为 epilogue 的库来解析请求,通过 sequelize reads/writes 到 MySQL 数据库,并将结果包装在 JSON 响应中。它将发送我为学生定义的所有字段以及我定义的任何 getter 的值。一切都很好。我已经能够使用尾声 POST、PUT、GET 并通常保持 MySQL 数据库更新。
但是,当我尝试定义 return 学生学校名称的 getter 方法时,事情变得棘手了。为此,我必须访问学校 table 中的记录并获取学校名称。
var school = sequelize.define("School", {
SchoolName: {
type: DataTypes.STRING,
},
}, {
classMethods: {
associate: function(models) {
school.hasMany(models.Student);
}
}
}
}
var student = sequelize.define("Student", {
FirstName: {
type: DataTypes.STRING,
},
LastName: {
type: DataTypes.STRING,
},
}, {
classMethods: {
associate: function(models) {
student.belongsTo(models.School);
},
},
getterMethods: {
FullName: function() {
return this.FirstName + ' ' + this.LastName; // This works just fine
},
SchoolName: function() {
return this.getSchool().SchoolName; // This doesn't work because getSchool is asynchronous
}
}
}
}
问题是 .getSchool() 是异步的,所以我似乎必须使用 .then 来访问结果。承诺对我来说是一个新概念,但我尝试过类似的事情:
SchoolName: function {
return this.getSchool.then(function(school) {
return school.SchoolName;
});
}
但这似乎只是 return 承诺本身,而不是承诺的结果,因为承诺在 getter return 时并未实现。所以,我最终向客户发送了类似的内容:
{
"FullName": "John Doe",
"SchoolName": {
"isFulfilled": false,
"isRejected": false
},
"id":1,
"FirstName":"John",
"LastName":"Doe"
}
这里的 getter 似乎必须是同步的,所以看起来我只需要一些方法来告诉 getter 停止并等待 Promise 完成然后 return 值。但这似乎违反了 node.js 的异步性质。所以,我有一种预感,我从根本上误解了一些关于 sequelize.js 或 node.js 或承诺甚至数据库设计的重要内容。有人可以重定向我吗?主要是,我想知道:正确的方法是什么?
是的,getSchool()
方法 returns 一个承诺。您需要让 sequelize 查询包含关联。您可以通过创建一个新的网络服务并放入您自己的 sequelize 查询来手动执行此操作,或者如果可以的话告诉 epilogue 执行此操作。看一个unit test in the epilogue code。也许您可以添加选项:associations: true
以加载关联。