我正在转换使用MariaDB的现有应用程序的后端来使用Sails(v0.10.0-rc7),并且我试图弄清楚如何获得填充到Role模型中的角色的所有权限给定我必须使用底层架构结构。
有三个表用于当前获取角色及其相关权限,工作查询如下所示:
SELECT pm.permission, pm.permkey
FROM role_master rm
INNER JOIN role_perm rp ON ( rm.roleid = rp.roleid )
INNER JOIN perm_master pm ON ( rp.permid = pm.permid )
WHERE rm.roleid = 1
GROUP By pm.permission
正如您所看到的,role_master
中的角色定义是role_perm
中每个角色的个人权限,最后是perm_master
中的权限定义。
我已经阅读了关于协会的this awesome wiki,但我没有看到任何可以帮助我的内容。
理想情况下,我最终想要的是一个输出的角色模型:
{
"id" : 1,
"name" : "My Role Name",
"description" : "My Role Description",
"permissions" : [ 'canread', 'canwrite', 'canjump', 'canplay' ]
}
在不修改底层数据库的情况下实现此目的的最佳方法是什么?
答案 0 :(得分:12)
Waterline的一个好处是能够将模型映射到自定义表和列名称。但是目前我们还没有为自动生成的连接表做一个很好的方法。我投入的早期作品之一是创建through
关联的能力。这些本质上允许您构建一个充当连接表的模型。我们后来决定这基本上只是一个嵌套的填充,但我在那里留下through
逻辑用于这样的用例。
您无法向直通表中添加其他属性,但如果您为连接表映射了两个值,则查询和蓝图路由将正常运行。现在有一个关于直通表所需的主键值的小注释,但这只是架构构建器中的一个错误,应尽快解决。
以下逻辑目前尚未记录,但可以帮助您获得所需的结果。
注意然而,这仍处于测试版发布状态,所以它还不会很稳固。我们没有在mysql适配器上进行正确的外连接调用,因此您将看到三个查询,然后结果将在应用程序层的内存中连接。这将被清理以执行单个SQL查询,就像您更新条件解析器时所期望的那样。
此外,无论何时使用现有数据,请确保您具有migrate: safe
标记,如下所示,因此不会对当前数据库应用任何更改。
// Role.js
module.exports = {
identity : 'Role',
tableName : 'role_master',
migrate : 'safe',
schema : true,
autoPK : false,
autoCreatedAt : false,
autoUpdatedAt : false,
attributes: {
id : {
columnName : 'rolefk',
type : 'string',
required : true,
primaryKey : true,
unique : true,
uuidv4 : true
},
// A Role can have many permissions through the roleperm model
permissions : {
collection : 'permission',
through: 'roleperm'
}
}
};
// Permission.js
module.exports = {
identity : 'Permission',
tableName : 'perm_master',
migrate : 'safe',
schema : true,
autoPK : false,
autoCreatedAt : false,
autoUpdatedAt : false,
attributes : {
id : {
columnName : 'permfk',
type : 'string',
required : true,
primaryKey : true,
unique : true,
uuidv4 : true
},
// A Permission can belong to many roles using the roleperm model
roles : {
collection: 'role',
through: 'roleperm'
}
}
};
// RolePerm.js
module.exports = {
identity : 'RolePerm',
tableName : 'role_perm',
migrate : 'safe',
schema : true,
autoPK : false,
autoCreatedAt : false,
autoUpdatedAt : false,
attributes : {
// Due to a bug in the schema generator this seems to be needed at the
// model level but not on the actual database.
id: {
type: 'integer',
primaryKey: true
},
roleid : {
model: 'role',
columnName: 'role_id'
},
permid : {
model: 'permission',
columnName: 'perm_id'
}
}
};