web-dev-qa-db-ja.com

Sequelizeを使用して複数のジャンクションテーブルに参加する

3つのプライマリテーブルを持つデータベースがあります:usersteams、およびfoldersは、2つのジャンクションテーブル_users_teams_および_teams_folders_によって結合されています。ユーザーとチームの間、およびチームとフォルダーの間には多対多の関係があります(ユーザーは複数のチームに所属でき、チームは複数のフォルダーを所有できます)。

Sequelizeは、ユーザーとチーム、およびチームとフォルダーの関係を管理するという素晴らしい仕事をしていますが、ユーザーとフォルダーの関係を確立する方法はありません。

生のSQLを使用せずに2つのジャンクションテーブルを結合する方法はありますか?

これをエレガントに、または合理的な数のステップで達成する方法はないようです。 user.getFolders()Folder.findAll({ include: [User] })などのメソッドを試しましたが、Sequelizeは3レベルの階層を理解できないようです。

28
jtschoonhoven

以下の関係を想定しています:

User.belongsToMany(Team, { through: 'users_teams'});
Team.belongsToMany(User, { through: 'users_teams'});

Folder.belongsToMany(Team, { through: 'teams_folders'});
Team.belongsToMany(Folder, { through: 'teams_folders'});

ネストされたインクルードを使用して、すべてを一度にロードできるはずです。

User.findAll({
  include: [
    {
      model: Team, 
      include: [
        Folder
      ]  
    }
  ]
});

あなたはあなたの投稿で与えた例ですでに正しい軌道に乗っているようです:)。変更する必要があるのは、includeにUserモデルを直接渡す代わりに、モデルプロパティとさらにネストされたincludeプロパティを持つオブジェクトを渡すことだけです

48

次のことに注意してください。

  • both Directionsでリレーションを定義します
  • correct orderにforeignKey、otherKeyがあることを確認してください
User.belongsToMany(Team, {
  through: 'users_teams',
  foreignKey: 'user_id',
  otherKey: 'team_id'
});

Team.belongsToMany(User, {
  through: 'users_teams',
  foreignKey: 'team_id',
  otherKey: 'user_id'
});
4
jmu