使用现有连接表的一对多关联

时间:2014-05-21 23:15:54

标签: sails.js

我正在转换使用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' ]
}

在不修改底层数据库的情况下实现此目的的最佳方法是什么?

1 个答案:

答案 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'
    }

  }

};
相关问题