在 Sequelize 中创建具有关联的实例

Creating instance with an association in Sequelize

使用 Sequelize,我创建了两个模型:UserLogin

一个用户可以有多个登录名,但是一个登录名必须只有一个用户,这意味着没有用户名不能保存一个登录名。

如何 .create 一次性登录一个用户关联?

当前代码(不起作用)

// Set up the models
var User = sequelize.define('User', {});
var Login = sequelize.define('Login', {});
Login.belongsTo(User, {
  onDelete: 'cascade',
  foreignKey: {
    field: 'userId',
    allowNull: false,
  }
});

// Create the instances
var user = User.create().then(function() {

  // THIS IS WHERE I WOULD LIKE TO SET THE ASSOCIATION
  var login = Login.create({
    userId: user.get('id')
  });

)};

以上结果为SequelizeValidationError: notNull Violation: UserId cannot be null

在您的 .then 中,回调接收上一次调用创建的模型实例。您需要在回调函数中指定参数。

var user = User.create().then(function(user) {

  // THIS IS WHERE I WOULD LIKE TO SET THE ASSOCIATION
  var login = Login.create({
    userId: user.get('id')
  });

  return login

}).then(function(login) {
    // all creation are complete. do something.
});

我还想指出的重要一点是您缺少 var 语句!这些很重要但与这个问题无关。参见 Declaring variables without var keyword

首先你需要设置两种方式的关系,像这样:

// Set up the models
var User = sequelize.define('User', {});
var Login = sequelize.define('Login', {});

// Set the correct associations
User.hasMany(Login, {})
Login.belongsTo(User, {});

然后,你需要正确获取promise返回的实例:

// Create the instances
User.create({}).then(function(newUser) {
    // now you can use newUser acessors to create the login
    return newUser.createLogin({});
).then(function(newLogin){
    // newLogin
}).catch(function(error){
    // error
});

假设您在用户和登录名之间有正确的关联, 您可以创建一个包括登录名的用户:

User.create({
   name: "name",
   Login: {...}
},{
   include: Login
})

您可以在此处找到更多信息: http://docs.sequelizejs.com/manual/tutorial/associations.html#creating-with-associations

我最近也遇到了同样的问题! 我的 foreignKey 配置有错别字。使用 field 而不是 name 导致了问题。

下面的更改将修复它。

{
    foreignKey: {
       name: 'userId',
       allowNull: false,
    }
}

@Arwed Mett 回答的更新

//Create Association Alias or just setting association alias by using 'as' keyword will also work
Login.User = Login.belongsTo(User);

User.create({
 name: "name",
  Login: {...}
}, {
  include: [{
    association: Login.User
  }]
});

参考 link - http://docs.sequelizejs.com/manual/tutorial/associations.html#creating-with-associations

此外,您还可以嵌套您的创作,使其更加有效和简洁。

  // Set up the models
    var User = sequelize.define('User', {});
    var Login = sequelize.define('Login', {});
        ...


    User.create({
       name: "name",
       Login:
            {
            users: {..i.e several users if a user belongs to another user..}
            }
        },{
       include:{
      model: Login,
      include: User //nested model.Create
         }
    })

如下所示:https://github.com/sequelize/sequelize/issues/7252

您在用户和登录名之间建立了关联,且约束 allowNull 为 false。您必须在用户之前创建登录或在模型中将 allowNull 设置为 true 并将 table 设置为 DB(LoginId Null 约束)

var User = sequelize.define('User', {});
var Login = sequelize.define('Login', {});
Login.belongsTo(User, {
  onDelete: 'cascade',
  foreignKey: {
    field: 'userId',
    allowNull: false,
  }
});

解决方案

Login.create({
   username: "username",
   User: {...}
},{
   include: User
})

对于像我这样试图创建包含另一个实例的模型实例的人,例如:

var login1 = await Login.create(...);
var user1 = await User.create({
    Login: login1
}, {
    include: Login
});

你不能,因为此方法用于嵌入一个实例(登录),该实例(登录)尚不存在,将在父实例(用户)创建级别创建。

因此,如果您想在新创建的用户中嵌入一个已经存在的登录名,请改为:

var login1 = await Login.create(...);
var user1 = await User.create({
    loginId: login1.get('id')
}, {});