引用单个表的多个列 - Sails JS API模型

Jhe*_*cht 7 javascript mysql node.js sails.js

最近我学习了Sails JS,虽然看起来非常有用(我不需要自己构建一个api?!)我正在测试帆的当前小项目遇到了一些麻烦.

我的主要职业是老师,整个项目的最终目标是列出学生,他们与(friend_id)合作的同学以及他们不合作的学生(unfriend_id).使用此信息以及他们当前的GPA,我想通过其他一些算法优化座位表.

第一部分,我需要从Sails数据服务器返回的数据与我达成一致.

我需要帆来做什么(我在一对多的集合以及多对多和多对一的情况下查看了帆文档,但这个问题似乎很特别)是收集所有的基于friend_idunfriend_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`)
);
Run Code Online (Sandbox Code Playgroud)

关系

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`)
);
Run Code Online (Sandbox Code Playgroud)

虚拟数据(忽略名称)

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);
Run Code Online (Sandbox Code Playgroud)

我尝试了类似下面的内容,但是当我运行它时,api为两者返回一个空的json数组(在我至少收到学生/关系列表之前,这取决于我正在寻找的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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

我现在对所有正在发生的事情并不是全新的,但我对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;
Run Code Online (Sandbox Code Playgroud)

使用collectionSails JS中的设置进行复制?

如果没有,我在哪里手动编写代码?(假设不是 StudentsController.js)

UPDATE

按照@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
  }
]
Run Code Online (Sandbox Code Playgroud)

更新#2

好吧,只是在等待时有点乱,我有一些非常简陋的工作.我进入Relationship.js文件并更改了student_idto 的定义,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
  }
]
Run Code Online (Sandbox Code Playgroud)

Jhe*_*cht -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'
        }
    }

};
Run Code Online (Sandbox Code Playgroud)

关系.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'
        }

    }
};
Run Code Online (Sandbox Code Playgroud)

然后我向api/models/目录中添加了两个新文件Friends.jsUnfriends.js,这两个文件都非常简单:

朋友.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'
        }
    }

};
Run Code Online (Sandbox Code Playgroud)

取消好友.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'
        }
    }

};
Run Code Online (Sandbox Code Playgroud)

输出

最重要的是“我得到正确的输出吗”,简短的回答是:不,但它是可用的。我还没有得到原始查询的 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
Run Code Online (Sandbox Code Playgroud)

本地主机的输出: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
Run Code Online (Sandbox Code Playgroud)

现在,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);
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

现在,为什么除了我在控制器中编写的代码之外的任何东西都表现得像现在这样,我不知道。但至少它正在发挥作用。