2017-09-15 62 views
0

在sequelize,如果我有这样的关联:多外键Sequelize

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

Sequelize会自动添加UserIdArticle表。但现在我想添加更多像UserNameEmailArticle,所以当我查询一篇文章我有作者的名字,我不需要再次查询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; 
}; 
+0

这是行不通的。外键必须映射到一个'用户',你可以有一个名字映射到许多用户。您基本上想要将用户表中的名称和电子邮件复制到文章表中。这不是一个好习惯。 –

回答

1

你并不需要运行2个查询获取用户信息。只需添加从Article一个belongsTo关系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模型有多个主键,可能无法按预期工作。如果你想使用复合主键,那么有一个单独的方法。

+0

非常感谢。另一个问题:我怎样才能在续集中定义这个模型:“用户可以编写很多文章,版主可以检查很多文章,版主是用户的一个子集”。我目前在'Article'表中添加了一个'checkedBy'列。还有其他方法吗? –