web-dev-qa-db-ja.com

多対多の逐次化-新しいレコードを作成して結合テーブルを更新する方法

Node、express、sequelizeを使用して単純なデータベースを構築しています。モデルを作成し、sequelizeがデータベースにテーブルを作成しました。

私にはUserとCityのモデルがあり、多対多の関係があります。 Sequelizeは、Usersテーブル、Citiesテーブル、および結合テーブルCitiesUsers:を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();
15
RickTakes

ドキュメントをさらに掘り下げた後、私は答えを見つけたと思います。

多対多の関係を作成する場合、sequelizeはget、set、およびメソッドを各モデルに作成します。

多対多のモデルのユーザーとプロジェクトを想定したドキュメントから: http://docs.sequelizejs.com/en/latest/docs/associations/#belongs-to-many-associations

これにより、メソッドにgetUsers、setUsers、addUsersがProjectに、getProjects、setProjects、addProjectがUserに追加されます。

したがって、私の場合、「city」はCity.findから返された特定のCityモデルです。

//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]);
  });      
});
8
RickTakes

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}))
6
Danny Sullivan

このスレッドの多くの優れた答えに追加するために、あるエンティティが別のエンティティを参照しているときに、そのエンティティがまだ存在しない場合(そして存在する場合のみ)に参照エンティティを作成したいと思っています。これには 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]));
  })
})
1
Matt Korostoff

Docs 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
Yassine Mokni