Node.js 通过关联创建续集

Node.js 通过关联创建续集,node.js,associations,sequelize.js,Node.js,Associations,Sequelize.js,我正在为两个类之间的关联开发一个create方法。sequelize文档表明,可以使用includes一步完成此操作 IntramuralAthlete.create(intramuralAthlete,{ include: [Person] }).then((data,err)=>{ if(data)res.json(data); else res.status(422).json(err); }).catch(fun

我正在为两个类之间的关联开发一个create方法。sequelize文档表明,可以使用includes一步完成此操作

IntramuralAthlete.create(intramuralAthlete,{
         include: [Person]
    }).then((data,err)=>{
         if(data)res.json(data);
         else res.status(422).json(err);
    }).catch(function(error) {
         res.status(422).json({message: "failed to create athlete", error: error.message});
});
我的模特协会是这样的

var Person = require('../models').person;
var IntramuralAthlete = require('../models').intramuralAthlete;

IntramuralAthlete.belongsTo(Person);
当我记录时,校内运动员的价值是

{ 
   person: 
   { firstName: 'Test',
     lastName: 'User',
     email: 'test@user.com'
  },
  grade: '12th',
  organizationId: 1 
}
但是我得到了错误
notNull违规:personId不能为null
。这个错误让我听起来像是我表示要在同一个调用中创建personId的方式出了问题

我在
create
语句中指出要用intraUraLathlet创建哪些关联表的方式是否有问题

谢谢

编辑: 我还尝试了以下结构,得到了相同的结果

{ 
  Person: { 
    firstName: 'Test',
    lastName: 'User',
    email: 'test@user.com'
 },
 grade: '12th',
 organizationId: 1 
}
我的模型如下:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('intramuralAthlete', {
    id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: sequelize.literal('CURRENT_TIMESTAMP')
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: sequelize.literal('CURRENT_TIMESTAMP')
    },
    grade: {
      type: DataTypes.STRING,
      allowNull: true
    },
    age: {
      type: DataTypes.INTEGER(11),
      allowNull: true
    },
    school: {
      type: DataTypes.STRING,
      allowNull: true
    },
    notes: {
      type: DataTypes.STRING,
      allowNull: true
    },
    guardianId: {
      type: DataTypes.INTEGER(11),
      allowNull: true,
      references: {
        model: 'contact',
        key: 'id'
      }
    },
    personId: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      references: {
        model: 'person',
        key: 'id'
      }
    },
    mobileAthleteId: {
      type: DataTypes.INTEGER(11),
      allowNull: true,
      references: {
        model: 'mobileAthlete',
        key: 'id'
      }
    },
    organizationId: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      references: {
        model: 'organization',
        key: 'id'
      }
    }
  }, {
    tableName: 'intramuralAthlete'
  });
};

我假设您的模型名为
Person
IntramuralAthlete
sequelize.define
方法的第一个参数)。在这种情况下,当您创建一个类似您的关联,并且没有将
定义为
属性时,您的
创建
数据对象应该如下所示

{
    Person: {
        firstName: 'Test',
        lastName: 'User',
        email: 'test@user.com'
    },
    grade: '12th',
    organizationId: 1 
}
如果您想改用
person
(就像在您的代码中一样),您应该稍微不同地定义关联

IntramuralAthlete.belongsTo(Person, { as: 'person' });
然后,您必须在
选项的
include
属性中的
create
查询中执行一些更改,如下所示

IntramuralAthlete.create(data, {
    include: [
        { model: Person, as: 'person' }
    ]
}).then((result) => {
    // both instances should be created now
});
EDIT:使用
personId的空值欺骗
save()
方法

如果这样做,您可以维护
allowNull:false

{
人:{
//个人数据
},
personId:'',//任何值-空字符串、空对象等。
年级:'12',
组织ID:1
}
编辑2:创建时禁用验证

本例假设验证已关闭。忽略模型验证似乎不是一个好主意,但是仍然保持数据库表级验证(在迁移中定义),在迁移中它仍然可以检查是否设置了
personId

intrauralathlete.create(数据、{
包括:[
{model:Person,as:'Person'}
],
验证:false
})。然后((结果)=>{
//现在应该创建这两个实例
});

在这种情况下,
数据
对象可以像您的示例中一样-不带
personId
属性。我们省略了允许传递
null
值的模型级验证,但是如果在
save()
方法期间,它仍然是
null
值-数据库级验证将抛出一个错误。

首先,当您将模型与belongsTo关联时,sequelize将自动将目标模型主键添加为源模型中的外键。在大多数情况下,您不需要自己定义它,因此在您定义
intrauralathlete.belongsTo(Person)
sequelize时,会将
PersonId
添加为
intrauralathlete
中的外键。您的
intracuralathlete
型号应如下所示:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('intramuralAthlete', {
    grade: {
      type: DataTypes.STRING,
      allowNull: true
    },
    age: {
      type: DataTypes.INTEGER(11),
      allowNull: true
    },
    school: {
      type: DataTypes.STRING,
      allowNull: true
    },
    notes: {
      type: DataTypes.STRING,
      allowNull: true
    }
 });
};
现在,您可以像上面的代码一样创建一个
intrauralathlete
。例如:

 let data = {
   Person: {
     firstName: 'Test',
     lastName: 'User',
     email: 'test@user.com'
   },
   grade: '12th',
   notes: 'test notes'
 }
IntramuralAthlete.create(data, {include: [Person]}).then((result) => {
// both instances should be created now
});
请注意型号名称。 其次,我假设您的
髓内
模型具有多个
belongsTo
关联。您只需将它们定义为上一个关联,sequelize将在
IntraUraLathlete
模型中将它们的主键添加为外键


第三,当您定义一个模型时,sequelize会自动添加一个
id
数据字段作为主键和自动增量,并且还会添加
createdAt
updatedAt
数据字段,其中包含一个默认的
当前时间戳
值,因此您不需要在模型中定义它们

您所说的内容是有意义的,但是我尝试了对对象结构的建议更改(包括在我的问题中的编辑),但失败了,并且出现了相同的错误。是的,这也可能发生。您是否也可以添加
IntramuralAthlete
模型定义代码?根据请求添加模型起初我没有考虑它-如果
personId
没有
allowNull:false
属性,我的答案就行了。在这种情况下,我需要重新思考。如果你有什么有用的东西,我会告诉你:)是的,就是这样。不太高兴的是,为了进行一次调用创建,您必须删除外键上的约束,但在我们的情况下,这比巨大的嵌套承诺链要好。谢谢你的帮助。