简体   繁体   中英

Creating associations between models

I am using Sequelize.js to create some tables. The models are User, Shop, Role and ShopUserRoles.

I have declared the models in the models/ folder like:

User.js

module.exports = function (sequelize, DataTypes) {
    var User = sequelize.define('User', {
        id : {
            type: DataTypes.STRING,
            unique: true,
            primaryKey : true
        },
        fullName : {
            type: DataTypes.STRING,
            field: 'full_name',
            allowNull : false
        },
    }, {
        tableName: 'users',

        classMethods: {
            associate: function(models) {
                User.hasMany(models.ShopUserRoles, {foreignKey: 'user_id' });
            }
        },
        timestamps: true,
        createdAt : 'created_at',
        updatedAt : 'updated_at'
    });

    return User;
};

Shop.js

module.exports = function(sequelize, DataTypes) {
    var Shop = sequelize.define('Shop', {
        id : {
            type : DataTypes.INTEGER,
            unique : true,
            primaryKey : true
        },
        shopName : {
            type : DataTypes.STRING,
            field : 'shop_name',
            allowNull : false
        },
        status : {
            type: DataTypes.STRING
        }
    }, {
        tableName : 'shops',

        classMethods : {
            associate : function(models) {
                Shop.hasMany(models.ShopUserRoles, {foreignKey : 'shop_id'});
            }
        },
        timestamps : true,
        createdAt : 'created_at',
        updatedAt: 'updated_at'
    });

    return Shop;
};

Role.js

module.exports = function(sequelize, DataTypes){
    var Role = sequelize.define('Role', {
        id : {
            type: DataTypes.INTEGER,
            unique: true,
            primaryKey: true
        },
        name : {
            type: DataTypes.STRING,
            unique: true
        }
    }, {
        tableName : 'roles',

        classMethods : {
            associate : function(models) {
                Role.hasMany(models.ShopUserRoles, {foreignKey: 'role_id'});
            }
        },
        timestamps : true,
        createdAt : 'created_at',
        updatedAt: 'updated_at'
    });

    return Role;
};

ShopUserRoles.js

module.exports = function(sequelize, DataTypes) {
    var ShopUserRoles = sequelize.define('ShopUserRoles', {
    }, {
        tableName : 'shop_user_roles',

        classMethods: {
            associate: function(models) {
                ShopUserRoles.belongsTo(models.User, {foreignKey: 'user_id' });
                ShopUserRoles.belongsTo(models.Shop, {foreignKey : 'shop_id'});
                ShopUserRoles.belongsTo(models.Role, {foreignKey: 'role_id'});
            }
        },
        timestamps : true,
        createdAt : 'created_at',
        updatedAt : 'updated_at'
    });

    return ShopUserRoles;
};

And I've imported them using sequelize['import'](FILENAME) format and added corresponding associations.

Now, as we have added associations, table shop_user_roles should be created AFTER the first three tables are generated, otherwise foreign key adding would not work. However, I am seeing that Sequelize is trying to create this table before users table is created. To remedy this, I have three options:

  • Assigning associations only AFTER the tables have been created
  • Assigning an explicit ordering of table creation or let Sequelize 'figure' things out intelligently
  • Trying to do the whole thing twice (which is clumsy and I wouldn't want it in development code)

As for the first two options, I am not exactly sure how to do those using Sequelize.js. Any kind of reference or help would be much appreciated.

I am using Sequelize.js v3.9.

Here's how I managed to solve this problem. Unfortunately it is a brute force attempt.

In my application, I was trying to export an array containing model names while maintaining the correct order. While we can get the associations between the models using the associate class method, it is also possible to hard-code the serial of table creation inside the classMethods property of models. For the User model, that could be like

classMethods: {
    serial: 1,
    associate: function(models) {
        User.hasMany(models.ShopUserRoles, {foreignKey: 'user_id' });
    }
}

Afterwards, a simple sort based on the hardcoded serial on the array containing these model names could do the trick.

Using the associations in order to make a Topologically sort would be a nicer approach as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM