首页 > 解决方案 > Sequelize 关联不正确

问题描述

我想建立这样的关系: erd

我希望每个用户都包含消息列表,并且每条消息都包含有关发件人的信息。与我发布的 ERD 相关。

我用于迁移的代码:

    module.exports = {
      up: (queryInterface, Sequelize) =>
        queryInterface.createTable('Messages', {
          id: {
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
            type: Sequelize.INTEGER,
          },
          text: {
            type: Sequelize.STRING,
            allowNull: false,
          },
          toUserId: {
            type: Sequelize.INTEGER,
            // TODO changed from CASCADE - not sure about change
            onDelete: 'CASCADE',
            references: {
              model: 'Users',
              key: 'id',
              as: 'toUserId',
            },
          },
          fromUserId: {
            type: Sequelize.INTEGER,
            // TODO changed from CASCADE - not sure about change
            onDelete: 'CASCADE',
            references: {
              model: 'Users',
              key: 'id',
              as: 'fromUserId',
            },
          },
          createdAt: {
            allowNull: false,
            type: Sequelize.DATE,
          },
          updatedAt: {
            allowNull: false,
            type: Sequelize.DATE,
          },
        }),
      down: (queryInterface /* , Sequelize */) =>
        queryInterface.dropTable('Messages'),
    };

module.exports = {
  up: (queryInterface, Sequelize) =>
    queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      firstName: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      lastName: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      lat: {
        allowNull: true,
        type: Sequelize.INTEGER,
      },
      lng: {
        allowNull: true,
        type: Sequelize.INTEGER,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATEONLY,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATEONLY,
      },
    }),
  down: (queryInterface /* , Sequelize */) => queryInterface.dropTable('Users'),
};

对于模型:

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    id: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER,
    },
    firstName: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    lastName: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    lat: {
      allowNull: true,
      type: DataTypes.INTEGER,
    },
    lng: {
      allowNull: true,
      type: DataTypes.INTEGER,
    },
    createdAt: {
      allowNull: false,
      type: DataTypes.DATEONLY,
    },
    updatedAt: {
      allowNull: false,
      type: DataTypes.DATEONLY,
    },
  });

  User.associate = (models) => {
    User.hasMany(models.Message, {
      foreignKey: 'toUserId',
      as: 'messages',
    });
  };

  return User;
};
module.exports = (sequelize, DataTypes) => {
  const Message = sequelize.define('Message', {
    id: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER,
    },
    text: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    createdAt: {
      allowNull: false,
      type: DataTypes.DATE,
    },
    updatedAt: {
      allowNull: false,
      type: DataTypes.DATE,
    },
  });

  Message.associate = (models) => {
    Message.belongsTo(models.User, {
      foreignKey: 'toUserId',
    });
  };
  return Message;
};

但是,当我尝试从 UserId 添加新消息时,显示为 Null 值。当我尝试获取消息时,它看起来像:

[
    {
        "id": 1,
        "text": "mytext",
        "createdAt": "2018-11-29T20:12:22.253Z",
        "updatedAt": "2018-11-29T20:12:22.253Z",
        "toUserId": 2,
        "User": {
            "id": 2,
            "firstName": "name1",
            "lastName": "name2",
            "lat": null,
            "lng": null,
            "createdAt": "2018-11-29",
            "updatedAt": "2018-11-29"
        }
    }
]

标签: expresssequelize.js

解决方案


根据您的说法,ERD我认为您relationships应该是这样的。

用户有很多消息

消息属于用户 在这种情况下,您的Message迁移应该是这样的。

id: {
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
            type: Sequelize.INTEGER,
          },
          text: {
            type: Sequelize.STRING,
            allowNull: false,
          },
          fromUserId: {
            type: Sequelize.INTEGER,
            // TODO changed from CASCADE - not sure about change
            onDelete: 'CASCADE',
            references: {
              model: 'Users',
              key: 'id',
            },
          },

请注意,我也删除了toUserId列和此别名as: 'fromUserId',

在您的User迁移中,您不需要更改任何内容是正确的。

在你的Message模型中

  Message.belongsTo(models.User, {
      foreignKey: 'fromUserId',
    });
  };

请注意,您只有一个FK,它是fromUserId

在你的User模型中。

User.associate = (models) => {
    User.hasMany(models.Message, {
      foreignKey: 'fromUserId',
    });
  };

完成所有这些后,您将能够获取属于user_id.


推荐阅读