簡體   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