【问题标题】:Has one association in Sequelize在 Sequelize 中有一个关联
【发布时间】:2021-03-16 01:56:53
【问题描述】:

我有一个用户模型,在角色模型上有一个 hasOne 关系

User.init({
    id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true
    },
    name: {
        type: DataTypes.STRING,
        allowNull: false
    },
    //email, password, and other fields, ...
    roleId: {
        type:DataTypes.INTEGER,
        allowNull: false
    }}, 
    {
        sequelize,
        tableName: "Users"
    });
User.hasOne(Role)

和榜样

Role.init({
    id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true
    },
    name: {
        type: DataTypes.STRING,
        allowNull: false
    }}, 
    {
        sequelize,
        tableName: "Roles"
    });

当我尝试用

创建一个新角色时
await Role.create(req.body)

请求是

POST http://localhost:3000/api/role
Content-Type: application/json
Authorization: Bearer <token>

{
    "name": "test role"
}

我收到错误column "UserId" does not exist

日志说:

routine: 'errorMissingColumn',
sql: 'INSERT INTO "Roles" ("id","name") VALUES (DEFAULT,$1) RETURNING "id","name","UserId";',
parameters: [
  'test role'
]

我在这里做错了什么?我的表只有Users表中的roleIdRoles表中的UserId是哪里来的?

迁移

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Roles', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
            type: Sequelize.STRING,
            allowNull: false
        }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Roles');
  }
};


'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        type: Sequelize.STRING
      },
      // other fields   
      roleId: {
          type: Sequelize.INTEGER,
          references: {
              model: "Roles",
              key: "id"
          }
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Users');
  }
};

如果我在角色模型中添加Role.belongsTo(User),我会收到错误:

models init error: TypeError: Cannot read property 'name' of undefined

【问题讨论】:

    标签: node.js sequelize.js associations model-associations


    【解决方案1】:

    对于要按照架构建议存储在用户表中的角色:User.belongsTo(Role) 将为您设置映射为 RoleId

    模型以与迁移相反的方式设置外键,因此导致缺少 UserID 列。

    除非您想自定义字段,否则不需要在架构中定义外键。然后在关联调用时定义 belongsTo/hasOne 选项。

    const { Sequelize, Model, DataTypes } = require('sequelize')
    const sequelize = new Sequelize('sqlite::memory:')
    
    class User extends Model {}
    class Role extends Model {}
    
    User.init({
        id: {
            type: DataTypes.INTEGER.UNSIGNED,
            autoIncrement: true,
            primaryKey: true
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false
        }}, 
        {
            sequelize,
            tableName: "Users"
        });
    
    Role.init({
        id: {
            type: DataTypes.INTEGER.UNSIGNED,
            autoIncrement: true,
            primaryKey: true
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false
        }}, 
        {
            sequelize,
            tableName: "Roles"
        });
    
    User.belongsTo(Role, { foreignKey: 'roleId' })
    

    那你就可以用关联做事了

    async function go(){
      await sequelize.sync()
      const role = await Role.create({ name: 'atester' })
      const user = await User.create({ name: 'test' })
      await user.setRole(role)
      
      console.log("%j", await User.findAll({ include: Role }))
    }
    
    go().catch(console.error)
    

    生成如下文档:

    {
      "id": 1,
      "name": "test",
      "createdAt": "2020-12-04T09:44:05.762Z",
      "updatedAt": "2020-12-04T09:44:05.763Z",
      "roleId": 1,
      "Role": {
        "id": 1,
        "name": "atester",
        "createdAt": "2020-12-04T09:44:05.758Z",
        "updatedAt": "2020-12-04T09:44:05.758Z"
      }
    }
    

    从那里您可以将迁移匹配到数据库。

    【讨论】:

    • 在创建关联并尝试类似user.setRole(role) 时,我总是收到错误Property 'setRole' does not exist on type 'User'.ts。我正在使用打字稿,如果这有什么不同的话。
    猜你喜欢
    • 2019-04-14
    • 2016-07-23
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多