最近我开始学习 Sails JS,虽然它看起来非常有用(我不必自己构建 api?!)我正在测试 sails 的当前小项目遇到了一些障碍。
我的主要职业是教师,整个项目的最终目标是列出学生、与他们一起工作的同伴(friend_id
),和他们不认识的学生 (unfriend_id
)。使用此信息,加上他们当前的 GPA,我想通过其他一些算法优化座位表。
第一部分,我需要从 Sails 数据服务器返回的数据与我一致。
我需要 sails 做的事情(我已经查看了一对多集合以及多对多和多对一集合中的 sails 文档,但这个问题似乎很特殊)是收集基于 friend_id
或 unfriend_id
列的用户的所有项目。
数据
This SqlFiddle具有基本架构设置和一些虚拟数据,供每个人复制/粘贴并在需要时直接使用。
用户
CREATE TABLE `students` (
`student_id` int(11) NOT NULL AUTO_INCREMENT,
`student_first_name` varchar(200) NOT NULL,
`student_last_name` varchar(255) NOT NULL,
`student_home_phone` varchar(10) DEFAULT NULL,
`student_guardian_email` varchar(255) DEFAULT NULL,
`student_gpa` float NOT NULL DEFAULT '2',
`class_id` tinyint(4) NOT NULL,
UNIQUE KEY `student_id` (`student_id`)
);
关系
CREATE TABLE `relations` (
`relation_id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) NOT NULL DEFAULT '100000',
`friend_id` int(11) DEFAULT NULL,
`unfriend_id` int(11) DEFAULT NULL,
UNIQUE KEY `relation_id` (`relation_id`)
);
虚拟数据(忽略名称)
INSERT INTO `students` VALUES (1,'Paul','Walker','1112223333','fake@email.com',2,1),(2,'Vin','Diesel','1112223333','fake@email.com',3,1),(3,'That','One\'Guy','1112223333','fake@email.com',4,1),(4,'Not','Yuagin','1112223333','fake@email.com',2,1),(5,'Hei','Yu','1112223333','fake@email.com',2,1);
INSERT INTO `relations` VALUES (1,1,2,NULL),(2,2,1,NULL),(3,1,NULL,4),(4,4,NULL,1),(5,1,5,NULL),(6,5,1,NULL),(7,2,3,NULL),(8,3,2,NULL);
我尝试了类似下面的操作,但是当我运行它时,api 为两者返回一个空的 json 数组(在此之前,我至少会收到一个学生/关系列表,具体取决于我正在查找的 api)。
学生.js
module.exports = {
connection:'localMysql',
schema: 'true',
attributes: {
student_id: {
type: "integer",
required: true,
unique: true,
primaryKey:true
},
student_first_name:{
type:'string'
},
student_last_name:{
type:'string'
},
student_home_phone:{
type:'integer'
},
student_guardian_email:{
type: 'email'
},
class_id:{
type:'integer'
},
friends:{
collection:'relationship',
via:'student_friends'
}
},
autoPK: false,
autoCreatedAt: false,
autoUpdatedAt: false
}
关系.js
module.exports = {
connection:'localMysql',
tableName:'relations',
attributes: {
relation_id:{
type: 'integer',
required: true,
unique: true,
primaryKey:true
},
student_id:{
type:'integer'
},
friend_id:{
type:'integer'
},
unfriend_id:{
type:'integer'
},
student_friends:{
collection:'students',
via:'student_id'
}
},
autoPK: false,
autoCreatedAt: false,
autoUpdatedAt: false
}
我对现在正在发生的所有事情都不是完全陌生,但我对 Node 和 Sails 还很陌生,所以我似乎只是摸不着头脑。如果我想要的东西不能通过集合模型完成,我应该在哪里放置代码来使这些交易发生?我假设(但你知道他们怎么说...)它会在 StudentsController.js
文件中吗?
Tl;博士
我能否获得此 MySQL 查询创建的行为:
select
s.*, group_concat(r.friend_id) as friends, group_concat(r.unfriend_id) as unfriends
from
students s
left join
relations r
ON s.student_id = r.student_id
GROUP BY s.student_id;
使用 Sails JS 中的 collection
设置进行复制?
如果没有,我应该将代码放在哪里以手动执行此操作? (假设它不是 StudentsController.js
)
更新
按照@Solarflare 的建议,我设法获得了一些内联的东西,尽管这是一个非常艰难的开始。现在我得到一个名为“关系”的列,但其中没有任何内容。这比以前我一无所获(因为返回的所有内容都是 []
)要好。但它是一个空数组。 (输出如下)。
注意:我从关系模型中删除了 student_friends
声明。
我该如何解决?
[
{
"relationships": [],
"student_id": 1,
"student_first_name": "Paul",
"student_last_name": "Walker",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [],
"student_id": 2,
"student_first_name": "Vin",
"student_last_name": "Diesel",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [],
"student_id": 3,
"student_first_name": "That",
"student_last_name": "One'Guy",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [],
"student_id": 4,
"student_first_name": "Not",
"student_last_name": "Yuagin",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [],
"student_id": 5,
"student_first_name": "Hei",
"student_last_name": "Yu",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
}
]
更新 #2
好吧,我只是在等待的时候四处乱逛,我得到了一些非常基本的工作。我进入 Relationship.js
文件并将 student_id
的定义更改为 model:'students',via:'student_id'
我可以至少获得给定学生的所有关系。它给了我正确的集合,但我仍然想知道是否有更直接的方法来摆弄它以获得我需要的东西。这是 localhost:1337/students
现在的输出:
[
{
"relationships": [
{
"relation_id": 1,
"friend_id": 2,
"unfriend_id": null,
"student_id": 1
},
{
"relation_id": 3,
"friend_id": null,
"unfriend_id": 4,
"student_id": 1
},
{
"relation_id": 5,
"friend_id": 5,
"unfriend_id": null,
"student_id": 1
}
],
"student_id": 1,
"student_first_name": "Paul",
"student_last_name": "Walker",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [
{
"relation_id": 2,
"friend_id": 1,
"unfriend_id": null,
"student_id": 2
},
{
"relation_id": 7,
"friend_id": 3,
"unfriend_id": null,
"student_id": 2
}
],
"student_id": 2,
"student_first_name": "Vin",
"student_last_name": "Diesel",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [
{
"relation_id": 8,
"friend_id": 2,
"unfriend_id": null,
"student_id": 3
}
],
"student_id": 3,
"student_first_name": "That",
"student_last_name": "One'Guy",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [
{
"relation_id": 4,
"friend_id": null,
"unfriend_id": 1,
"student_id": 4
}
],
"student_id": 4,
"student_first_name": "Not",
"student_last_name": "Yuagin",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"relationships": [
{
"relation_id": 6,
"friend_id": 1,
"unfriend_id": null,
"student_id": 5
}
],
"student_id": 5,
"student_first_name": "Hei",
"student_last_name": "Yu",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
}
]
最佳答案
好的,所以这里的全部内容非常简单,我把我的代码放在上面并在这里和那里做了一些更改,老实说,我认为它不会起作用,但我得到了更好的东西比我之前得到的一无所有。这不是一个完美的解决方案,但目前它运行良好。
这是文件,以及我所做的:
学生.js
module.exports = {
connection: 'localMysql',
autoPK: false,
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
student_id: {
type: "integer",
required: true,
unique: true,
primaryKey: true
},
student_first_name: {
type: 'string'
},
student_last_name: {
type: 'string'
},
student_home_phone: {
type: 'integer'
},
student_guardian_email: {
type: 'email'
},
class_id: {
type: 'integer'
},
friends:{
collection:'relationship',
via:'student_id'
},
unfriends:{
collection:'relationship',
via:'student_id'
}
}
};
关系.js
module.exports = {
connection: 'localMysql',
autoPK: false,
autoCreatedAt: false,
autoUpdatedAt: false,
tableName:'relations',
attributes: {
relation_id: {
type: 'integer',
required: true,
unique: true,
primaryKey: true
},
student_id: {
model:'students',
via:'student_id'
},
friend_id: {
model:'students',
via:'student_id',
through:'friends'
},
unfriend_id: {
model:'students',
via:'student_id',
through:'unfriends'
}
}
};
然后我在 api/models/
目录中添加了两个新文件,Friends.js
和 Unfriends.js
,它们都很漂亮简单:
friend .js
module.exports = {
connection: 'localMysql',
schema: false,
autoPK: false,
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
student_id:{
model:'students',
via:'student_id'
},
friend_id:{
model:'relationship',
via:'friend_id'
}
}
};
取消好友
module.exports = {
connection: 'localMysql',
schema: false,
autoPK: false,
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
student_id:{
model:'students',
via:'student_id'
},
unfriend_id:{
model:'relationship',
via:'unfriend_id'
}
}
};
输出
最重要的是“我是否得到了正确的输出”,简短的回答是:没有,但它是可用的。我还没有得到原始查询的 Sails 表示,但我已经接近了。
localhost:1337/relationship 的输出
[
{
"student_id": {
"student_id": 1,
"student_first_name": "Paul",
"student_last_name": "Walker",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
"friend_id": {
"student_id": 2,
"student_first_name": "Vin",
"student_last_name": "Diesel",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
"relation_id": 1
},
{
"student_id": {
"student_id": 1,
"student_first_name": "Paul",
"student_last_name": "Walker",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
"unfriend_id": {
"student_id": 4,
"student_first_name": "Not",
"student_last_name": "Yuagin",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
"relation_id": 3
},
//Truncated for space
localhost:1337/students/的输出
[
{
"friends": [
{
"relation_id": 1,
"student_id": 1,
"friend_id": 2,
"unfriend_id": null
},
{
"relation_id": 3,
"student_id": 1,
"friend_id": null,
"unfriend_id": 4
},
{
"relation_id": 5,
"student_id": 1,
"friend_id": 5,
"unfriend_id": null
}
],
"unfriends": [
{
"relation_id": 1,
"student_id": 1,
"friend_id": 2,
"unfriend_id": null
},
{
"relation_id": 3,
"student_id": 1,
"friend_id": null,
"unfriend_id": 4
},
{
"relation_id": 5,
"student_id": 1,
"friend_id": 5,
"unfriend_id": null
}
],
"student_id": 1,
"student_first_name": "Paul",
"student_last_name": "Walker",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},//Truncated for length
现在,在 StudentsController.js
中,我完成了一个方法,它给了我更多我想要的东西。
StudentsController.js
module.exports = {
get:function(req,res){
Students.find()
.populate('friends',{
'friend_id':{'!':null}
})
.populate('unfriends',{
'unfriend_id':{'!':null}
}).exec(function(err,j){
if(err) res.json(err);
res.json(j);
});
}
};
localhost:1337/students/get 的输出(这更接近我想要的/students
[
{
"friends": [
{
"relation_id": 1,
"student_id": 1,
"friend_id": 2,
"unfriend_id": null
},
{
"relation_id": 5,
"student_id": 1,
"friend_id": 5,
"unfriend_id": null
}
],
"unfriends": [
{
"relation_id": 3,
"student_id": 1,
"friend_id": null,
"unfriend_id": 4
}
],
"student_id": 1,
"student_first_name": "Paul",
"student_last_name": "Walker",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
},
{
"friends": [
{
"relation_id": 2,
"student_id": 2,
"friend_id": 1,
"unfriend_id": null
},
{
"relation_id": 7,
"student_id": 2,
"friend_id": 3,
"unfriend_id": null
}
],
"unfriends": [],
"student_id": 2,
"student_first_name": "Vin",
"student_last_name": "Diesel",
"student_home_phone": "1112223333",
"student_guardian_email": "fake@email.com",
"class_id": 1
}//Truncated for length
现在,为什么除了我在 Controller 中编写的代码之外的任何东西都以现在的方式运行,我不知道。但至少它在起作用。
关于javascript - 引用单个表的多列 - Sails JS API 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37154223/