Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper way to add associations when multiple files and table definitions? #3736

Closed
Bondifrench opened this issue May 17, 2015 · 1 comment
Closed

Comments

@Bondifrench
Copy link

Hi,
I have different files which define the different schemas of my tables and one index file that aggregates them and normally associate the tables if needed.
This is my index.js:

var fs = require('fs')
    , path = require('path')
    , Sequelize = require('Sequelize')
    , configDB = require('../../config/configMs')
    , sequelize = new Sequelize(configDB.dbname, configDB.user, configDB.password,{
        host: 'xxx.xx.net',
        dialect: "mssql"
    })
    , db2 = {};
fs
    .readdirSync(__dirname)
    .filter(function (file) {
        return (file.indexOf('.') !== 0) && (file !== 'index.js')
    })
    .forEach(function (file) {
        var model = sequelize.import(path.join(__dirname, file));
        db2[model.name] = model;
    })
Object.keys(db2).forEach(function (modelName) {
    if (db2[modelName].options.hasOwnProperty('associate')) {
        db2[modelName].options.associate(db2)
    }
});
module.exports = Sequelize.Utils._.extend({
    sequelize: sequelize,
    Sequelize: Sequelize
}, db2) 

Then I have these schemas:
first reportData.js

module.exports = function(sequelize, DataTypes) {
    var reportData = sequelize.define('reportData', {
        Id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            allowNull: false
        },
        PrefixId: {
            type: DataTypes.INTEGER,
            field: 'PrefixId',
            referencesKey: 'PrefixId'
        },
        ConceptId: {
            type: DataTypes.INTEGER,
            field: 'ConceptId',
            referencesKey: 'ConceptId'
        },
        RootConceptId: {
            type: DataTypes.INTEGER,
            field: 'RootConceptId',
            referencesKey: 'RootConceptId'
        },
        ReportPeriodId: {
            type: DataTypes.INTEGER,
            field: 'ReportPeriodId',
            referencesKey: 'ReportPeriodId'
        },
        Value: DataTypes.DECIMAL,
    }, {
        schema: 'Domain',
        tableName: 'FactReport',
        freezeTableName: true,
        timestamps: false,
        classMethods: {
            associate: function(models) {
                reportData.belongsTo(models.reportPeriod);
                reportData.belongsTo(models.rootConcept);
            }
        }
    });
    return reportData;
}

then reportPeriod.js:

module.exports = function(sequelize, DataTypes) {
    var reportPeriod = sequelize.define('ReportPeriod', {
        Id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            allowNull: false
        },
        Description: {
            type: DataTypes.STRING(200)
        },
    }, {
        schema: 'Domain',
        tableName: 'ReportPeriod',
        freezeTableName: true,
        timestamps: false
    });
    return reportPeriod;
}

then rootConcept.js:

module.exports = function(sequelize, DataTypes) {
    var rootConcept = sequelize.define('RootConcept', {
        Id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            allowNull: false
        },
        OriginRoot: {
            type: DataTypes.STRING(500),
            field: 'OriginRoot'
        }
    }, {
        schema: 'Domain',
        tableName: 'RootConcept',
        freezeTableName: true,
        timestamps: false
    });
    return rootConcept;
}

My query is the following:

db2.reportData.findAll({
            attributes: ['Value', 'FiscalYear', 'PreOrder'],
                include: [
                {
                    model: db2.reportPeriod, 
                    attributes: ['Description'],
                },
                {
                    model: db2.rootConcept,
                    attributes: ['OriginRoot']
                }],
                order: ['PreOrder']
            })
            .then(function(content) {
                res.json(content);
            })
            .catch(function(error) {
                console.log('Error retrieving as reported data: ', error);
            });

I get [TypeError: Cannot call method 'getTableName' of undefined].
So my first question is: is the classMethods in reportData.js the correct way to associate models, as I see when I examin my db2 object that it doesn't associate anything.
Does the order matter? as I can see that files that contain the different files that defines every table are called in alphabetical order which makes reportPeriod being called after reportData has been defined.
Or should I put the different table associations in index.js and in that case how?
Thx

@janmeier
Copy link
Member

When you define sequelize.define('RootConcept', { the model will be stored as db.RootConcept. In your associate function you are trying to access reportData.belongsTo(models.rootConcept); (lower case r)

Closing this issue, since it is neither a bug report nor a feature request.

For general sequelize questions, please use StackOverflow or Google groups.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants