问题
I am using Sequelize.js to do a double join on the same table. I have a set of Team objects and a set of Game objects. A team hasMany Games, so it would have foreign keys in the game table, but there are two teams in every game so i need to join the table twice. What is the best way to do this using the sequelize ORM.
Team = sequelize.define('teams',{
name : Sequelize.STRING,
location : Sequelize.STRING,
});
Game = sequelize.define('games',{
homeTeamId : Sequelize.INTEGER,
awayTeamId : Sequelize.INTEGER,
location : Sequelize.STRING,
});
// Associations
Game.hasOne(Team, {foreignKey : 'homeTeamId'});
.hasOne(Team, {foreignKey : 'awayTeamId'});
Team.hasMany(Game);
Thanks!
回答1:
That is an interresting question actually. This is not supported in sequelize at the moment, but it is definitely do-able. I've outlined two ways below:
var Sequelize = require('./index');
var sequelize = new Sequelize('sequelize_test', 'root', null, {
host: "127.0.0.1",
port: 3306
});
var Team = sequelize.define('teams',{
name : Sequelize.STRING,
location : Sequelize.STRING
}, {
instanceMethods: {
getGamesOne: function () {
var chainer = new Sequelize.Utils.QueryChainer();
chainer.add(this.getHomeGames());
chainer.add(this.getAwayGames());
return new Sequelize.Utils.CustomEventEmitter(function (emitter) {
chainer.run().done(function (err, results) {
var home = results[0],
away = results[1];
if (err) emitter.emit('error', err)
else emitter.emit('success', home.concat(away));
});
}).run();
},
getGamesTwo: function () {
return Game.findAll({ where: ["homeTeamId = ? OR awayTeamId = ?", this.id, this.id ]})
}
}
});
var Game = sequelize.define('games',{
homeTeamId : Sequelize.INTEGER,
awayTeamId : Sequelize.INTEGER,
location : Sequelize.STRING
});
// Associations
Game.belongsTo(Team, {foreignKey : 'homeTeamId'})
.belongsTo(Team, {foreignKey : 'awayTeamId'});
Team.hasMany(Game, { as: 'AwayGames', foreignKey : 'awayTeamId'});
Team.hasMany(Game, { as: 'HomeGames', foreignKey : 'homeTeamId'});
Team.find(1).done(function (err, team) {
team.getGamesOne().done(function(err, games) {
console.log(games);
});
team.getGamesTwo().done(function(err, games) {
console.log(games);
});
})
GetGamesOne uses sequelize's assocations to fetch home games and away games seperately and join the before returning them to you. GetGamesTwo manually builds a query, so you only talk to the DB once. Pick whichever you prefer - in one it may not be very clear what is going on, but you are using sequelize to build the query so even if you change the names of the keys later on it will still work. Two is very short and clear, but you have to handle the query yourself.
I also changed your relation from game to team to belongsTo
- meaning that the foreign key is in the game table.
Have fun using Sequelize ;-)
来源:https://stackoverflow.com/questions/14527136/sequelize-js-join-table-twice-using-hasmany