2017-09-15 2 views
0

In sequelize, wenn ich einen Verein wie haben:Multi Fremdschlüssel auf hasMany Verein Sequelize

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

Sequelize automatisch UserId Spalte Article Tabelle hinzufügen. Aber jetzt möchte ich mehr wie UserName und Email zu Article hinzufügen, also wenn ich einen Artikel abfrage, habe ich den Namen des Autors und ich muss nicht erneut von UserId abfragen.

Wie kann ich das tun? Ich habe versucht,

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

aber nur UserId erscheinen in Article Tabelle.

Hier ist mein User-Modell:

"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

Dies wird nicht funktionieren. Der Fremdschlüssel muss einem "Benutzer" zugeordnet werden und Sie könnten einen "Namen" haben, der vielen Benutzern zugeordnet ist. Sie möchten grundsätzlich die Namen und E-Mails aus der Benutzertabelle in die Artikeltabelle kopieren. Dies ist keine gute Übung. –

Antwort

1

Sie brauchen nicht zwei Abfragen ausführen Benutzerinformationen zu erhalten. Fügen Sie einfach eine belongsTo Beziehung von Article zu User

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

und fragen Sie die Artikel wie dieser

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

Sie das Ergebnis in folgendem Format haben:

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

Auf einem separaten Notiz Ihr User Modell verfügt über mehrere Primärschlüssel, die möglicherweise nicht wie erwartet funktionieren. Wenn Sie einen zusammengesetzten Primärschlüssel verwenden möchten, gibt es dafür einen separaten Ansatz.

+0

Vielen Dank. Eine andere Frage: Wie kann ich dieses Modell in Sequelize definieren: "Ein Benutzer kann viele Artikel schreiben. Ein Moderator kann viele Artikel überprüfen. Ein Moderator ist eine Untergruppe von Benutzern". Ich füge gerade eine 'checkedBy' Spalte zu' Article' Tabelle hinzu. Irgendwo anders? –

Verwandte Themen