[英]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.