3

同じテーブルで二重結合を行うために Sequelize.js を使用しています。Team オブジェクトのセットと Game オブジェクトのセットがあります。チームには多くのゲームがあるため、ゲーム テーブルに外部キーがありますが、すべてのゲームに 2 つのチームがあるため、テーブルに 2 回参加する必要があります。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);

ありがとう!

4

1 に答える 1

4

それは実際には興味深い質問です。現時点では、これは続編ではサポートされていませんが、確実に実行可能です。以下に2つの方法を概説しました。

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は、sequelizeのアソシエーションを使用して、ホームゲームとアウェイゲームを別々にフェッチし、参加してから返却します。GetGamesTwoは手動でクエリを作成するため、DBとの通信は1回だけです。どちらかを選択してください。1つでは何が起こっているのかはっきりしないかもしれませんが、クエリを作成するためにsequelizeを使用しているので、後でキーの名前を変更しても機能します。2つは非常に短く明確ですが、クエリを自分で処理する必要があります。

また、ゲームからチームへの関係を変更しましbelongsToた。つまり、外部キーがゲームテーブルにあります。

Sequelizeを楽しんでください;-)

于 2013-01-29T17:05:05.267 に答える