使用Sequelize.import时定义模型的顺序

时间:2016-07-06 02:26:48

标签: node.js sequelize.js

我现在正在使用Sequelize,一个node.js orm。根据示例,我的代码如下:

module.exports = function(callback){

  var fs = require('fs');
  var path = require('path');
  var Sequelize = require('sequelize');
  var logger = require(path.join(__dirname, '../logger/logger.js'));
  var settings = JSON.parse(fs.readFileSync(path.join(__dirname, '../../config/settings.json'), 'utf8'));
  var dbConnectionInfo = require(path.join(__dirname, '../../lib/util/dbConnectionInfo.js'))(settings.dbUri);
  var sequelize = new Sequelize(dbConnectionInfo.dbUri,{logging:false});

  sequelize.authenticate()
.then(function() {
  if (callback) {
    callback();
  }
})
.catch(function(error) {
  logger.error('DB Connection failed ', error);
  if (callback) {
    callback(error);
  }
});
  var db = {};

  fs
.readdirSync(__dirname)
.filter(function(file) {
  return file.indexOf('.') !== 0 && file !== 'index.js';
})
.forEach(function(file) {
  var model = sequelize.import(path.join(__dirname, file));
  db[model.name] = model;
});

  db.sequelize = sequelize;
  return db;

}

此代码将加载“model”文件夹中的所有文件。 问题是有一个参考模型B的模型A,如下所示:

var A = function(sequelize, DataTypes) {
  return sequelize.define('A', {
    serviceInstanceId: {
  type: DataTypes.STRING,
  field: 'b_id',
  allowNull: false,
  references: {
    model: B,
    key: "b_id",
    deferrable: sequelize.Deferrable.INITIALLY_IMMEDIATE
  }
},

  });
    };

但是我发现当模型A初始化时,它会尝试找到模型B,而模型B现在没有加载。那么是否有一种方法可以确保当它尝试加载A时,B将首先加载?

1 个答案:

答案 0 :(得分:2)

当您在单独的文件中定义模型时,我不认为您可以定义这样的关联。您必须先导入所有模型,并且在导入所有模型后,您可以运行关联逻辑。

有几种方法可以做到这一点但是常用的方法和我使用的方法是为处理关联的模型定义associate classMethod。

模型A

module.exports = function (sequelize, DataTypes) {
    var A = sequelize.define('A', {}, {
        classMethods: {
            associate: function (models) {
                A.belongsTo(models.B, {foreignKey: 'b_id'});
            }
        }
    });
    return A;
};

模型B

module.exports = function (sequelize, DataTypes) {
    var B = sequelize.define('B', {}, {
        classMethods: {
            associate: function (models) {
                B.hasMany(models.A, {foreignKey: 'b_id'});
            }
        }
    });
    return B;
};

一旦你有了这样的模型声明并且导入了所有模型,你可以为模型调用associate函数。

Object.keys(db).forEach(function (modelName) {
  if ("associate" in db[modelName]) {
    models[modelName].associate(db);
  }
});

这可以放在索引文件的导入逻辑之后。