paulovitorjp paulovitorjp - 1 year ago 344
MySQL Question

Helper methods and associations with include not working on sequelize

I can't call the helper methods that should have been generated by sequelize when using belongsTo/hasMany. And I cannot eager load a table.
When trying to run the helper methods I get a message saying there is no such method, and when trying to use findAll with include passing the other table it says that the tables are not associated, please see details below:

models directory:

./models
--ticket.js
--category.js
--index.js


ticket.js

'use strict';

module.exports = function(sequelize, DataTypes) {
var Ticket = sequelize.define('Ticket', {
// category_id: DataTypes.INTEGER,
subject: DataTypes.STRING,
description: DataTypes.TEXT,
requester_name: DataTypes.STRING,
requester_email: DataTypes.STRING,
owner_email: DataTypes.STRING,
status: {
type: DataTypes.ENUM,
values: ['opened', 'in progress', 'closed']
}
}, {
underscored: true,
classMethods: {
associate: function(models) {
// associations can be defined here
Ticket.belongsTo(models['Category']);
Ticket.hasMany(models['Interaction']);
}
}
});

return Ticket;
};


category.js

'use strict';

module.exports = function(sequelize, DataTypes) {
var Category = sequelize.define('Category', {
name: DataTypes.STRING
}, {
underscored: true,
classMethods: {
associate: function(models) {
// associations can be defined here
Category.hasMany(models['Ticket']);
}
}
});
return Category;
};


index.js

'use strict';

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

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

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

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

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

module.exports = db;


Then I create constants for the models:

const models = require('../models'),
Ticket = models['Ticket'],
Category = models['Category'];


When trying to call Ticket.getCategory(), like below:

Ticket.findById(req.params.ticket_id).then((ticket) => {
ticket.getCategory().then((category)=>{
ticket['category'] = category;
res.json(ticket);
});
});


I get:

Executing (default): SELECT `id`, `subject`, `description`, `requester_name`, `requester_email`, `owner_email`, `status`, `created_at`, `updated_at` FROM `Tickets` AS `Ticket` WHERE `Ticket`.`id` = '1';
Unhandled rejection TypeError: ticket.getCategory is not a function


If I try to use eager loading, like below:

Ticket.findAll({where:{id:req.params.ticket_id},include:[Category]}).then((ticket) => {
res.json(ticket);
});


I get:

Unhandled rejection SequelizeEagerLoadingError: Category is not associated to Ticket!


What am I doing wrong?

Thanks in advance!

Answer Source

As you said you are using seqielize ^4.2.0, which is major update API has little changes.'

In version 4 you shouldn't add class methods through classMethods object, instead you should do this.

var Ticket = sequelize.define('Ticket', {
    // category_id: DataTypes.INTEGER,
    subject: DataTypes.STRING,
    description: DataTypes.TEXT,
    requester_name: DataTypes.STRING,
    requester_email: DataTypes.STRING,
    owner_email: DataTypes.STRING,
    status: {
      type: DataTypes.ENUM,
      values: ['opened', 'in progress', 'closed']
    }
  }, {
    underscored: true,
});

Ticket.associate = function(models) {
    // associations can be defined here
    Ticket.belongsTo(models['Category']);
    Ticket.hasMany(models['Interaction']);
};

You can read how to upgrade from sequelize 3 to 4 here

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download