引用单个表的多列 – Sails JS API Model

最近我学习了Sails JS,虽然看起来非常有用( 我不需要自己创build一个API ),但是现在我正在testing的小项目已经遇到了一些麻烦。

我的主要职业是一名教师,而整个项目的最终目标是要有一个学生名单,他们与( friend_id )工作良好的friend_id ,以及他们没有( friend_id )的学生。 使用这些信息,加上他们目前的GPA,我想通过一些其他algorithm来优化座位表。

第一部分,我需要从Sails数据服务器返回的数据同意我的看法。

我所需要做的事情(我已经在一对多集合以及多对多和多对一的情况下查看了帆的文档,但是这个问题似乎是特别的)是收集所有的基于friend_idfriend_id列的用户的项目。

数据

这个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数组(在我至less会收到一个学生/关系列表,这取决于我正在查找的api)。

Students.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 } 

Relationship.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查询创build的行为:

 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

UPDATE

按照@Solarflare的build议,我已经设法让一些内联,虽然这是一个非常粗糙的开始。 现在我得到一个名为“关系”的专栏,但没有任何内容。 哪一个比之前我什么都没有得到(比如所有返回的是[] )更好。 但这是一个空arrays。 (输出在下面)。

注意:我从关系模型中删除了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' ,我至less可以获得给定学生的所有关系。 它给了我正确的collections,但我仍然想知道是否有一个更直接的方法来摆脱这个得到我所需要的东西。 这里是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 } ] 

好吧,这里完整的东西是非常简单的,我把我的代码放在上面,在这里和那里做了一些改变,老实说,没有想到它会工作,但我得到的东西比我之前得到的一切都好。 这不是一个完美的解决scheme,但现在它运作得很好。

这里是文件,我做了什么:

Students.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' } } }; 

Relationship.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.jsUnfriends.js ,这两个都非常简单:

Friends.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' } } }; 

Unfriends.js

 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表示,但我已经接近了。

本地主机:1337 /关系的输出

 [ { "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(这更接近我想要的那个/学生

 [ { "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 

现在为什么除了我在控制器中写的代码以外,其他任何东西都是现在的样子,我没有任何线索。 但至less它工作。