node最佳实践6-sequelize 多对多关联

473 阅读1分钟

![](secure2.wostatic.cn/static/457a… 2023-02-08 at 14.58.36.png?auth_key=1678172671-neTgzNJ2KASCYDRZub8wdX-0-3077cf012e187d8dbe86e1f23792eee2)

Author和Category可以通过Book实现多对多关联

author.js

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Author extends Model {
    static associate(models) {
      Author.hasMany(models.Book,{
        foreignKey: {
          name: "authorId"
        }
      })
      Author.belongsToMany(models.Category,{through: 'Book',foreignKey: 'authorId'})
    }
  }
  Author.init({
    name: DataTypes.STRING
  }, {
    sequelize,
    modelName: 'Author'
  });
  return Author;
};

category.js

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Category extends Model {
    static associate(models) {
      Category.hasMany(models.Book,{
        foreignKey: {
          name: "categoryId"
        }
      })
      Category.belongsToMany(models.Author,{through: 'Book',foreignKey: 'categoryId'})
    }
  }
  Category.init({
    name: DataTypes.STRING
  }, {
    sequelize,
    modelName: 'Category',
  });
  return Category;
};

关联关系也可以写在models/index.js里,比如:

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const process = require('process');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (
      file.indexOf('.') !== 0 &&
      file !== basename &&
      file.slice(-3) === '.js' &&
      file.indexOf('.test.js') === -1
    );
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
    db[model.name] = model;
  });
Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});
db.Author.belongsToMany(db.Category,{through: 'Book',foreignKey: 'authorId'})
db.Category.belongsToMany(db.Author,{through: 'Book', foreignKey: 'categoryId'})

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

category.controller.js新增一个getCategoryAuthors方法,根据category类型获取author

export const getCategoryAuthors = (req,res) => {
  const { id } = req.body
  Category.findAll({
    where: {id},
    attributes: ['id','name'],
    include: {model: Author,attributes: ['id','name']}
  }).then(authors => {
    return res.json(Result.success(authors))
  }).catch(err => {
    return res.status(500).json(Result.failed(err))
  })
}

Screenshot 2023-03-07 at 15.31.47.png