Sequelize 中的“有很多通过”关联

Don*_*n P 4 sequelize.js

假设我们有三个模型:

  • 图书
  • 章节
  • 段落

以下是他们的关联:

  • 有很多章节
  • 章节有很多段落
  • 有很多段落,通过章节

是否可以与 Sequelize 定义“有很多,通过”关系?如果是这样,如何?

以下是 Book、Chapter 和 Paragraph 的非常基本的模型:

// Book model
const Book = sequelize.define('Book', {
  id: {
    type: DataTypes.INTEGER,
    allowNull: false,
    primaryKey: true
  },
  title: {
    type: DataTypes.STRING
  }
}, {
  classMethods: {
    associate: (models) => {
      Book.hasMany(models.Chapter, {
        foreignKey: 'bookId',
        as: 'chapters'
      });
    }
    // How can you add an association for a book having many paragraphs, through chapters?
  }
});


// Chapter model
const Chapter = sequelize.define('Chapter', {
  id: {
    type: DataTypes.INTEGER,
    allowNull: false,
    primaryKey: true
  },
  title: {
    type: DataTypes.STRING
  }
}, {
  classMethods: {
    associate: (models) => {
      Chapter.hasMany(models.Paragraph, {
        foreignKey: 'chapterId',
        as: 'paragraphs'
      });

      Chapter.belongsTo(models.Book, {
        foreignKey: 'bookId'
      });
    }
  }
});


// Paragraph Model
const Paragraph = sequelize.define('Paragraph', {
  id: {
    type: DataTypes.INTEGER,
    allowNull: false,
    primaryKey: true
  },
  content: {
    type: DataTypes.TEXT
  }
}, {
  classMethods: {
    associate: (models) => {
      Paragraph.belongsTo(models.Chapter, {
        foreignKey: 'chapterId'
      });
    }
    // How can you add an association for paragraphs belonging to a book "through" chapters?
  }
});
Run Code Online (Sandbox Code Playgroud)

pio*_*ias 5

不幸的是,没有这种可能性。你可以做的是创造一些instanceMethods对双方BookParagraph模型一样getParagraphs,并getBook以检索相关元素

// in Book model
instanceMethods: {
    getParagraphs: function(options){
        options.include = [
            {
                model: sequelize.models.Chapter,
                attributes: [],
                where: {
                    bookId: this.get('id')
                }
            }
        ];

        return sequelize.models.Paragraph.findAll(options);
    }
}
Run Code Online (Sandbox Code Playgroud)

上述方法将返回其章节属于指定书籍的所有段落。你可以getBookParagraph模型中做相反的事情。

另一方面,为了检索包含所有章节及其段落的书籍,您只需执行findAll嵌套include(开玩笑提醒一下)。