Search code examples
node.jssequelize.js

Where to define sequelize associations


I'm using sequelize in my Node js app. All of the models are defined in separate files named, for instance, user.js, message.js and so on. I also have the index.js file that's auto-generated, here's a snippet of it, you'll probably recognize it:

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');
  })
  .forEach(file => {
    const model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

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

So I'm looking at the associations manual of sequelize here. The thing I can't figure out is where this would go in my case, since I'm using the auto-generated index.js file which gathers all the models. In their example, as you can see on the link, they've got something like:

const A = sequelize.define('A', /* ... */);
const B = sequelize.define('B', /* ... */);

A.hasOne(B); // A HasOne B
A.belongsTo(B); // A BelongsTo B
A.hasMany(B); // A HasMany B
A.belongsToMany(B, { through: 'C' }); 

How would I do the same thing when my models are spread across multiple files? I've tried something like this (for instance, in the message model):

  return sequelize.define('message', {
    message_id: {
      type: DataTypes.BIGINT,
      allowNull: false,
      autoIncrement:true,
      primaryKey: true
    },
    user_id: {
      type: DataTypes.BIGINT,
      allowNull: true
    }
    // and other stuff..
  }, {
    tableName: 'message'
  }).hasOne(require('./user'));
};

which gives an error: message.hasOne called with something that's not a subclass of Sequelize.Model

Any ideas?

Thanks.


Solution

  • Here's how I do it:

    module.exports = (sequelize, DataTypes) => {
      const MyEntity = sequelize.define(
        'MyEntity',
        {
          name: DataTypes.STRING
        },
        {}
      );
      MyEntity.associate = function(models) {
        // associations can be defined here
        MyEntity.hasMany(models.OtherEntity, {
          foreignKey: 'myEntityId',
          as: 'myEntities'
        });
      };
      return MyEntity;
    };