繁体   English   中英

Bookshelf.js中的多表关系

[英]Multitable relationship in bookshelf.js

我正在尝试使用bookshelf.js作为Postgresql的ORM在node.js应用程序中实现基于角色的访问控制。 我有以下架构:

USERS <- USERS_ROLES -> ROLES <- ROLES_RIGHTS -> RIGHTS

我希望能够获得用户拥有的所有权利。 在sql中,我只会这样做:

SELECT rights.*
FROM rights
INNER JOIN roles_rights ON roles_rights.right_id=rights.id
INNER JOIN users_roles ON users_roles.role_id = roles_rights.role_id
WHERE users_roles.user_id=1
GROUP BY rights.id

作为Bookshelf.js的新手,我在弄清楚如何建立关系方面遇到一些麻烦。 这是我的第一次尝试:

const User = bookshelf.Model.extend({

  tableName: 'users',

  roles: function() {
    return this.belongsToMany(Role, 'users_roles', 'user_id', 'role_id')
  },

  rights: function() {
    return this.belongsToMany(Right, 'users_roles', 'user_id', 'role_id')
      .query(qb => qb
        .innerJoin('roles_rights', 'roles_rights.right_id', 'rights.id')
      )
  }

})

const Role = bookshelf.Model.extend({

  tableName: 'roles',

  rights: function() {
    return this.belongsToMany(Right, 'roles_rights', 'role_id', 'right_id')
  },

  users: function() {
    return this.belongsToMany(User, 'users_roles', 'user_id', 'role_id')
  }

})

const Right = bookshelf.Model.extend({

  tableName: 'rights',

  roles: function() {
    return this.belongsToMany(Role, 'users_roles', 'user_id', 'role_id')
  }

})

这没用... :-(

最终,我想使此查询起作用:

User.where({ id: req.user.get('id') })
  .fetch({ withRelated: ['rights'] })
  .then(user => {
    ...
  })
})

任何帮助将不胜感激!

在同一个问题上苦苦挣扎了一段时间之后,这是我最接近可用解决方案的方法。

无需对您描述的模型进行任何修改(从User模型中删除rights关系除外),您可以执行以下操作:

User.where({ id: req.user.get('id') })
  .fetch({ withRelated: ['roles.rights'] })
  .then(user => {
    console.log(JSON.stringify(user));
  })
})

我发现这对于我的用例来说是更好的选择,因为我将始终拥有可用的用户角色和角色权限。

像这样:

{
  id: 12
  roles: [
    {
      id: 21,
      rights: [
        {
          id: 11,
          name: 'DELETE'
        }
      ]
    }
  ]
}

如果您确实希望用户具有所有用户角色所拥有的所有权限,则可以使用Bookshelf的virtuals插件并创建一个虚拟行。

const User = bookshelf.Model.extend({

  tableName: 'users',

  roles: function() {
    return this.belongsToMany(Role, 'users_roles', 'user_id', 'role_id')
  },

  virtuals: {
    rights: {
      get: function () {
        const rightsIds = new Set();
        return this.related('roles').reduce((rights, group) => {
          return group.related('rights').reduce((rights, right) => {
            if (!rightsIds.has(right.id)) {
              rightsIds.add(right.id);
              rights.push(right);
            }
            return rights;
          }, rights);
        }, []);
      }
    }
  },
});

像这样使用它:

User.where({ id: req.user.get('id') })
  .fetch({ withRelated: ['roles.rights'] })
  .then(user => {
    console.log(JSON.stringify(user.get('rights'));
  })
})

初始化书架时必须启用virtuals插件:

bookshelf.plugin(['virtuals']);

这不是最优雅的解决方案,但是如果您想用书架做所有事情,就是这样。 每当书架让我失望时,我只会使用knex (这knex发生)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM