【问题标题】:Multi foreign key on hasMany association SequelizehasMany关联Sequelize上的多外键
【发布时间】:2017-09-17 22:49:44
【问题描述】:

在续集中,如果我有这样的关联:

User.hasMany(models.Article, { onDelete: 'cascade', hooks: true});

Sequelize 会自动将UserId 列添加到Article 表中。但是现在我想在Article 中添加更多类似UserNameEmail 的内容,所以当我查询一篇文章时,我有作者姓名,我不需要再通过UserId 查询。

我该怎么做?我试过了

User.hasMany(models.Article, { onDelete: 'cascade', hooks: true, foreignKey: {'UserId': 'id', 'UserName': 'name' } });

但它只有UserId 出现在Article 表中。

这是我的用户模型:

"use strict";
var bcrypt = require('bcryptjs');

module.exports = function (sequelize, DataTypes) {
  var User = sequelize.define('User', {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true
    },
    name: {
      type: DataTypes.STRING,
      primaryKey: true
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false
    },
    email: {
      type: DataTypes.STRING,
      primaryKey: true
    },
    role: {
      type: DataTypes.STRING,
      allowNull: false
    },
    activeToken: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    status: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
      allowNull: false
    },
    avatar: {
      type: DataTypes.STRING,
      allowNull: true
    },
    phone: {
      type: DataTypes.STRING,
      allowNull: true
    }
  }, {
      instanceMethods: {
        updatePassword: function (newPass, callback) {
          var self = this;
          bcrypt.genSalt(10, function (err, salt) {
            bcrypt.hash(newPass, salt, function (err, hashed) {
              self.update({
                password: hashed
              }).then(callback);
            });
          });
        },
        updateStatus: function (status, callback) {
          this.update({
            status: status
          }).then(callback);
        },
        comparePassword: function (password, callback) {
          bcrypt.compare(password, this.password, function (err, isMatch) {
            if (err) {
              throw err;
            }
            callback(isMatch);
          });
        },
        updateRole: function (newRole, callback) {
          this.update({
            role: newRole
          }).then(callback);
        }
      },
      classMethods: {
        createUser: function (newUser, callback) {
          bcrypt.genSalt(10, function (err, salt) {
            bcrypt.hash(newUser.password, salt, function (err, hash) {
              newUser.password = hash;
              User.create(newUser).then(callback);
            });
          });
        },
        getUserById: function (id, callback) {
          var query = {
            where: {
              id: id
            }
          }
          User.findOne(query).then(callback);
        },
        getUserByUsername: function (username, callback) {
          var query = {
            where: {
              username: username
            }
          };
          User.findOne(query).then(callback);
        },
        getUserByEmail: function (email, callback) {
          var query = {
            where: {
              email: email
            }
          };
          User.findOne(query).then(callback);
        },
        getAllUser: function (callback) {
          User.findAll().then(callback);
        },
        deleteUser: function (userId, callback) {
          var query = {
            where: {
              id: userId
            }
          };

          User.destroy(query).then(callback);
        },
        associate: function (models) {
          User.hasMany(models.Article, { onDelete: 'cascade', hooks: true, onUpdate: 'cascade', foreignKey: {'UserId': 'id', 'UserName': 'name' } });
          User.hasMany(models.Comment, { onDelete: 'cascade', hooks: true, onUpdate: 'cascade' });
          User.hasMany(models.Device, { onDelete: 'cascade', hooks: true, onUpdate: 'cascade' });
        }
      },
      tableName: 'User'
    });
  return User;
};

【问题讨论】:

  • 这行不通。外键必须映射到一个User,您可以有一个映射到多个用户的name。您基本上想将姓名和电子邮件从用户表复制到文章表。这不是一个好的做法。

标签: node.js sequelize.js


【解决方案1】:

您无需运行 2 个查询即可获取用户信息。只需将belongsTo 关系从Article 添加到User

User.hasMany(models.Article, { onDelete: 'cascade', hooks: true});
Article.belongsTo(models.User);

并像这样查询文章

Article.findAll({ where: <condition>, include: {
    model: User,
    attributes: ['name', 'email']
} });

您将获得以下格式的结果:

[.....
   {
       articleId: 23,
       articleTitle: "<Some String>",
       User: {
           name: "User Name",
           email: "User Email"
       }
   }
   ........
]

另外,您的User 模型有多个主键,它们可能无法按预期工作。如果您想使用复合主键,则可以使用单独的方法。

【讨论】:

  • 非常感谢。另一个问题:如何在sequelize中定义这个模型:“一个用户可以写很多文章。一个版主可以检查很多文章。版主是用户的一个子集”。我目前正在向Article 表添加一个checkedBy 列。还有什么办法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 2019-04-01
  • 1970-01-01
  • 2021-07-25
  • 2021-04-21
  • 1970-01-01
相关资源
最近更新 更多