Model Association
iwanjunaid opened this issue · 4 comments
I wonder how to implement model association in this plugin as shown in sequelize site
var Player = this.sequelize.define('Player', {/* attributes */})
, Team = this.sequelize.define('Team', {/* attributes */});
Player.belongsTo(Team);
@iwanjunaid Had the same question. A quick look into the code revealed that a little nice third-party module called sqlizr is used.
@iwanjunaid this plugin use to handle that itself and then one of the users built a little module called sqlizr to handle the imports and associations and this plugin has been using that for a little while now.
You can add your associations in your classMethods on the sequelize.define options arg http://docs.sequelizejs.com/en/latest/api/sequelize/#definemodelname-attributes-options-model
{
tableName: 'state',
classMethods: {
associate: function(db) {
State.belongsTo(db.Country);
State.belongsTo(db.Zone);
}
},
getterMethods: {
},
setterMethods: {
}
}
I'll add this to the readme
I could only get this to work with some modifications. It kept complaining that what was passed to the method was not a model.
I wanted set up a couple "belongsToMany" associations and added the associate classMethods. Once the associate is called I can see the foreign keys added when sync is called. But there does not seem to be any "get" or "add" methods added. I don't know if it is due to hapi-sequelized or sequelize.
Here is are the models Game and GameUser
var Game = function(sequelize, DataTypes){
sequelize.define(
'Game',
{
gid: {
type: DataTypes.INTEGER.UNSIGNED,
unique: true,
allowNull: false,
autoIncrement: true,
primaryKey : true
},
game_type: {
type: DataTypes.INTEGER(6)
},
game_status: {
type: DataTypes.INTEGER(6),
},
start_time: {
type: DataTypes.DATE
}
},
{
tableName: 'games',
timestamps: true,
classMethods: {
associate: function(model) {
return this.belongsToMany(model.GameUser, {through:'Player', foreignKey:'gid'});
}
},
getterMethods:{
game_type: function(){
return this.getDataValue('game_type') == 1 ? "free" : "prize";
}
},
setterMethods:{
game_type: function(value){
var t = value == "free" ? 1 : 2;
return this.setDataValue('game_type', t);
}
}
}
);
};
module.exports = Game
var GameUser = function(sequelize, DataTypes){
sequelize.define(
'GameUser',
{
uid: {
type: DataTypes.INTEGER.UNSIGNED,
unique: true,
allowNull: false,
autoIncrement: true,
primaryKey : true
},
user_name: {
type: DataTypes.STRING
},
email: {
type: DataTypes.STRING
},
balance: {
type: DataTypes.DECIMAL(10,2)
},
status: {
type: DataTypes.STRING
}
},
{
tableName: 'users',
timestamps: true,
classMethods: {
associate: function(model) {
return this.belongsToMany(model.Game, {through:'Player', foreignKey:'uid'});
}
},
}
);
};
module.exports = GameUser
Player
var Player = function(sequelize, DataTypes){
sequelize.define(
'Player',
{
pid: {
type: DataTypes.INTEGER.UNSIGNED,
unique: true,
allowNull: false,
autoIncrement: true,
primaryKey : true
},
gid: {
type: DataTypes.INTEGER.UNSIGNED
},
uid: {
type: DataTypes.INTEGER.UNSIGNED
},
credits: {
type: DataTypes.DECIMAL(10,2)
},
status: {
type: DataTypes.STRING
},
unreg_at: {
type: DataTypes.DATE
}
},
{
tableName: 'players',
timestamps: true
}
);
};
module.exports = Player;
The associate is done just before server start and db.sync();
var Composer = require('./index');
Composer(function (err, server) {
if (err) {
throw err;
}
var db = server.plugins['hapi-sequelized'].db;
var Models = db.sequelize.models;
var Game = Models.Game;
var GameUser = Models.GameUser;
Game.associate(Models);
GameUser.associate(Models);
db.sequelize.sync().then(function() {
console.log('models synced');
server.start(function () {
console.log('Started the plot device on port ' + server.info.port);
});
});
});
And the output from the sync():
Executing (default): CREATE TABLE IF NOT EXISTS `players` (`pid` INTEGER UNSIGNED NOT NULL auto_increment UNIQUE , `gid` INTEGER UNSIGNED, `uid` INTEGER UNSIGNE
D, `credits` DECIMAL(10,2), `status` VARCHAR(255), `unreg_at` DATETIME, `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL, UNIQUE `players_uid_gid_
unique` (`gid`, `uid`), PRIMARY KEY (`pid`), FOREIGN KEY (`gid`) REFERENCES `games` (`gid`) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (`uid`) REFERENCES
`users` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `players`
When I try to use the methods that the sequelize docs say are supposed to be created, they are not available. http://docs.sequelizejs.com/en/latest/docs/associations/#belongs-to-many-associations
server.route({
method: 'GET',
path: options.basePath + '/games/{id}',
config: {
auth: {
strategy: 'session',
scope: ['admin','account']
}
},
handler: function (request, reply) {
var Models = request.server.plugins['hapi-sequelized'].db.sequelize.models;
var Game = Models.Game;
Game.getGameUsers().then( function (err, game) {
if (err) {
return reply(err);
}
if (!game) {
return reply({ message: 'Record not found.' }).code(404);
}
reply(game);
});
// });
}
});
I have tried "getGameUser()", "getGameUsers", getusers(), getuser() and none of them exist. Is this an issue with this module or sequelize or am I doing something wrong?
+1
I noticed there are no associations in the README and the test/ folder. The code from @ADumaine might be a good template for a test. Is this issue closed when it should be opened, or should a new one be re-opened?