Angularjs:通过关系的多对多
Angularjs: Many-to-Many with Through Relationship
在我的应用程序中,我有 学生 可以 Enroll Classes.
注册记录开始和结束日期以及Class。
Class 包含详细信息,例如 class 名称和描述。
Student (1) - (N) Enrollment (1) - (1) Class
Therefore
Student (1) - (N) Class
这就是我希望对象的样子。
{
"studentId": 1,
"name": "Henrietta",
"enrolledClasses": [
{
"enrollmentId": 12,
"startDate": "2015-08-06T17:43:14.000Z",
"endDate": null,
"class":
{
"classId": 15,
"name": "Algebra",
"description": "..."
}
},
"enrollmentId": 13,
"startDate": "2015-08-06T17:44:14.000Z",
"endDate": null,
"class":
{
"classId": 29,
"name": "Physics",
"description": "..."
}
}
}
但是我的 RESTful API 无法(轻松地)输出关系的完整嵌套结构,因为它的 ORM 不能通过关系实现多对多。所以我得到了学生和他们的多个注册,但只是对每个 class 的引用,而不是详细信息。我需要显示详细信息,而不仅仅是一个 Id。
我可以等待学生对象可用,然后使用引用为每个 classId 对 API 进行额外调用以获取详细信息,但我不确定如何,或者即使,然后将其与学生对象集成。
这是我目前所拥有的。
function findOne() {
vm.student = StudentsResource.get({
studentId: $stateParams.studentId
});
};
这是我从 API
中得到的
{
"studentId": 1,
"name": "Henrietta",
"enrolledClasses": [
{
"enrollmentId": 12,
"startDate": "2015-08-06T17:43:14.000Z",
"endDate": null,
"class": 15
},
"enrollmentId": 13,
"startDate": "2015-08-06T17:44:14.000Z",
"endDate": null,
"class": 29
}
}
对于 class 的详细信息,我可以一次一个地添加它们,但还没有弄清楚如何等到学生对象可用时将它们推入其中。也不知道如何正确推动它们...
{
"classId": 15,
"name": "Algebra",
"description": "..."
}
{
"classId": 29,
"name": "Physics",
"description": "..."
}
问题
通过注册将学生和 class(es) 详细信息合并为一个对象是否是一种好的做法?
- 如果是这样,最明确的方法是什么?
- 如果不是,还有什么有效的方法?
请记住,该应用程序将允许更改学生详细信息和注册,但不应允许更改 class 姓名或描述的详细信息。因此,如果 Angular 为对象发送 PUT,则不应尝试发送任何 class 的详细信息,而应仅发送参考。这将强制服务器端保护数据,但为避免错误,客户端不应尝试。
作为背景,我在后台使用 SailsJS 和 PostgreSQL API。
所以基本上在 Sailsjs 方面,您应该覆盖 StudentController.js 中的 findOne 函数。这是假设您使用的是蓝图。
// StudentController.js
module.exports = {
findOne: function(req, res) {
Student.findOne(req.param('id')).populate('enrollments').then(function(student){
var studentClasses = Class.find({
id: _.pluck(student.enrollments, 'class')
}).then(function (classes) {
return classes
})
return [student, classes]
}).spread(function(student, classes){
var classes = _.indexBy(classes, 'id')
student.enrollments = _.map(student.enrollments, function(enrollment){
enrollment.class = classes[enrollment.class]
return enrollment
})
res.json(200, student)
}).catch(function(err){
if (err) return res.serverError(err)
})
}
}
// Student.js
module.exports = {
attributes: {
enrollments: {
collection: 'enrollment',
via: 'student'
}
// Rest of the attributes..
}
}
// Enrollment.js
module.exports = {
attributes: {
student: {
model: 'student'
}
class: {
model: 'class'
}
// Rest of the attributes...
}
}
// Class.js
module.exports: {
attributes: {
enrollments: {
collection: 'enrollment',
via: 'class'
}
// Rest of the attrubutes
}
}
说明:
1. 使用 Lo-dash 的 _.pluck 函数重新调整了一个 classId 数组,我们找到了我们想要填充的所有 classes。然后我们使用 promise 链 .spread(),创建一个由 classid 索引的数组,并将 classId 映射到我们想要填充到学生返回的注册中的实际 class 实例来自 Student.findOne()。
2. Return 入学率很高的学生 class.
来源:Sails.js populate nested associations
在我的应用程序中,我有 学生 可以 Enroll Classes.
注册记录开始和结束日期以及Class。
Class 包含详细信息,例如 class 名称和描述。
Student (1) - (N) Enrollment (1) - (1) Class
Therefore
Student (1) - (N) Class
这就是我希望对象的样子。
{
"studentId": 1,
"name": "Henrietta",
"enrolledClasses": [
{
"enrollmentId": 12,
"startDate": "2015-08-06T17:43:14.000Z",
"endDate": null,
"class":
{
"classId": 15,
"name": "Algebra",
"description": "..."
}
},
"enrollmentId": 13,
"startDate": "2015-08-06T17:44:14.000Z",
"endDate": null,
"class":
{
"classId": 29,
"name": "Physics",
"description": "..."
}
}
}
但是我的 RESTful API 无法(轻松地)输出关系的完整嵌套结构,因为它的 ORM 不能通过关系实现多对多。所以我得到了学生和他们的多个注册,但只是对每个 class 的引用,而不是详细信息。我需要显示详细信息,而不仅仅是一个 Id。
我可以等待学生对象可用,然后使用引用为每个 classId 对 API 进行额外调用以获取详细信息,但我不确定如何,或者即使,然后将其与学生对象集成。
这是我目前所拥有的。
function findOne() {
vm.student = StudentsResource.get({
studentId: $stateParams.studentId
});
};
这是我从 API
中得到的{
"studentId": 1,
"name": "Henrietta",
"enrolledClasses": [
{
"enrollmentId": 12,
"startDate": "2015-08-06T17:43:14.000Z",
"endDate": null,
"class": 15
},
"enrollmentId": 13,
"startDate": "2015-08-06T17:44:14.000Z",
"endDate": null,
"class": 29
}
}
对于 class 的详细信息,我可以一次一个地添加它们,但还没有弄清楚如何等到学生对象可用时将它们推入其中。也不知道如何正确推动它们...
{
"classId": 15,
"name": "Algebra",
"description": "..."
}
{
"classId": 29,
"name": "Physics",
"description": "..."
}
问题
通过注册将学生和 class(es) 详细信息合并为一个对象是否是一种好的做法?
- 如果是这样,最明确的方法是什么?
- 如果不是,还有什么有效的方法?
请记住,该应用程序将允许更改学生详细信息和注册,但不应允许更改 class 姓名或描述的详细信息。因此,如果 Angular 为对象发送 PUT,则不应尝试发送任何 class 的详细信息,而应仅发送参考。这将强制服务器端保护数据,但为避免错误,客户端不应尝试。
作为背景,我在后台使用 SailsJS 和 PostgreSQL API。
所以基本上在 Sailsjs 方面,您应该覆盖 StudentController.js 中的 findOne 函数。这是假设您使用的是蓝图。
// StudentController.js
module.exports = {
findOne: function(req, res) {
Student.findOne(req.param('id')).populate('enrollments').then(function(student){
var studentClasses = Class.find({
id: _.pluck(student.enrollments, 'class')
}).then(function (classes) {
return classes
})
return [student, classes]
}).spread(function(student, classes){
var classes = _.indexBy(classes, 'id')
student.enrollments = _.map(student.enrollments, function(enrollment){
enrollment.class = classes[enrollment.class]
return enrollment
})
res.json(200, student)
}).catch(function(err){
if (err) return res.serverError(err)
})
}
}
// Student.js
module.exports = {
attributes: {
enrollments: {
collection: 'enrollment',
via: 'student'
}
// Rest of the attributes..
}
}
// Enrollment.js
module.exports = {
attributes: {
student: {
model: 'student'
}
class: {
model: 'class'
}
// Rest of the attributes...
}
}
// Class.js
module.exports: {
attributes: {
enrollments: {
collection: 'enrollment',
via: 'class'
}
// Rest of the attrubutes
}
}
说明:
1. 使用 Lo-dash 的 _.pluck 函数重新调整了一个 classId 数组,我们找到了我们想要填充的所有 classes。然后我们使用 promise 链 .spread(),创建一个由 classid 索引的数组,并将 classId 映射到我们想要填充到学生返回的注册中的实际 class 实例来自 Student.findOne()。
2. Return 入学率很高的学生 class.
来源:Sails.js populate nested associations