在Sequelize中“有很多通过”协会

时间:2017-03-10 01:56:20

标签: 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?
  }
});

1 个答案:

答案 0 :(得分:4)

不幸的是没有这种可能性。您可以做的是在instanceMethodsBook模型上创建一些Paragraph,例如getParagraphsgetBook,以便检索相关元素

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

上述方法将返回其章节属于指定书籍的所有段落。您可以对getBook模型中的Paragraph执行相反的操作。

另一方面,为了检索包含所有章节及其段落的书籍,您只需使用嵌套findAll执行include(提醒相关内容)。