Sequelize.js join table twice using hasMany

倾然丶 夕夏残阳落幕 提交于 2019-12-22 10:43:54

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!