Reputation: 538
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!
Upvotes: 0
Views: 3703
Reputation: 2047
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
Upvotes: 1
Reputation: 5041
The problem is that your associations are not completely done. You need to specify a foreign key. For example:
module.exports = function(sequelize, DataTypes) {
var Ticket = sequelize.define('Ticket', {
//blablabla
}, {
underscored: true,
classMethods: {
associate: function(models) {
// here specify which are your foreign keys
// category_id is just to illustrate
Ticket.belongsTo(models['Category'], {foreignKey: category_id});
Ticket.hasMany(models['Interaction'], {foreignKey: something_id});
}
}
});
return Ticket;
};
This also needs to be done in the counterpart, Category and Interaction in this case. Then you will be able to use the sequelize magic
Upvotes: 1