Sequelize Many to Many - 如何创建新记录和更新连接表

问题描述 投票:12回答:4

我正在构建一个带有node,express和sequelize的简单数据库。我已经创建了我的模型,并且sequelize在我的数据库中创建了表。

我有模特用户和城市,有很多关系。 Sequelize创建了表Users,Cities和一个连接表CitiesUsers:with UserId和CityId。

我的问题是,当我创建新用户时,如何更新该连接表?在创建时忽略CityId属性。

   //Models use 
   //City.hasMany(User);
   //User.hasMany(City);

   var user = User.build({
      first_name: 'John',
      last_name: 'Doe',
      CityId: 5
    });

    user.save();
javascript mysql sequelize.js
4个回答
8
投票

在深入研究文档之后,我相信我找到了答案。

在创建多对多关系时,sequelize会为每个模型创建get,set和add方法。

从文档假设模型用户和项目有很多到很多:http://docs.sequelizejs.com/en/latest/docs/associations/#belongs-to-many-associations

这将添加方法getUsers,setUsers,addUsers到Project,以及getProjects,setProjects和addProject到User。

所以在我的情况下,我做了以下“城市”是从City.find返回的特定城市模型...

//user.setCities([city]);

models.User.find({ where: {first_name: 'john'} }).on('success', function(user) {
  models.City.find({where: {id: 10}}).on('success', function(city){
    user.setCities([city]);
  });      
});

5
投票

一旦创建了City和User模型,就可以创建用作连接表的模型的新实例。

const User = sequelize.define('user')
const City = sequelize.define('city')
const UserCity = sequelize.define('user_city')

User.belongsToMany(City, { through: UserCity })
City.belongsToMany(User, { through: UserCity })

Promise.all([User.create(), City.create()])
    .then(([user, city]) => UserCity.create({userId: user.id, cityId: city.id}))

1
投票

来自文档v3:

// Either by adding a property with the name of the join table model to the object, before creating the association
project.UserProjects = {
  status: 'active'
}
u.addProject(project)

// Or by providing a second argument when adding the association, containing the data that should go in the join table
u.addProject(project, { status: 'active' })


// When associating multiple objects, you can combine the two options above. In this case the second argument
// will be treated as a defaults object, that will be used if no data is provided
project1.UserProjects = {
    status: 'inactive'
}

u.setProjects([project1, project2], { status: 'active' })
// The code above will record inactive for project one, and active for project two in the join table

1
投票

只是为了补充这个线程中的许多优秀答案,我发现一般情况下,当我有一个实体引用另一个时,我想创建引用的实体,如果(并且只有)它还不存在。为此,我喜欢使用findOrCreate()

因此,想象一下您正在存储文章,每篇文章都可以包含任意数量的标签。你通常想做的是:

  1. 迭代所有想要的标签,并检查它们是否存在。如果它们尚不存在则创建它们。
  2. 找到或创建所有标签后,创建您的文章。
  3. 创建文章后,将其链接到您在步骤1中查找(或创建)的标记。

对我来说,这看起来像:

const { article, tags } = model.import("./model/article");

let tagging = [
  tags.findOrCreate({where: {title: "big"}}),
  tags.findOrCreate({where: {title: "small"}}),
  tags.findOrCreate({where: {title: "medium"}}),
  tags.findOrCreate({where: {title: "xsmall"}})
];

Promise.all(tagging).then((articleTags)=> {
  article.create({
    title: "Foo",
    body: "Bar"    
  }).then((articleInstance) => {
    articleInstance.setTags(articleTags.map((articleTag) => articleTag[0]));
  })
})
© www.soinside.com 2019 - 2024. All rights reserved.