Sequelize - findOrCreate on the “through” table, on belongsToMany association

First of all, I'm rather new to Node.JS and even newer to Sequelize, and this has been bothering me for a while. I have the following Model entities:

Match.js

module.exports = function(sequelize, DataTypes) {
    var Match = sequelize.define('Match', {
            matchId: {
                type: DataTypes.BIGINT,
                field: 'match_id'
            },
            server: {
            type: DataTypes.STRING
            },
            (...)
            rankedBoo: {
                type: DataTypes.BOOLEAN,
                field: 'ranked_boo'
            }
    }, {
        classMethods: {
            associate: function(models) {
                Match.belongsToMany(models.Summoner, {as: 'Participants', through: 'SummonerMatch'});
            }
        },
        freezeTableName: true,
        underscored: true
    });

  return Match;
};

Summoner.js

module.exports = function(sequelize, DataTypes) {
  var Summoner = sequelize.define('Summoner', {
        summonerId: {
            type: DataTypes.INTEGER,
            field: 'summoner_id'
        },
        server: {
            type: DataTypes.STRING
        },
        summonerName: {
            type: DataTypes.STRING,
            field: 'summoner_name'
        },
        mainChampion: {
            type: DataTypes.INTEGER,
            field: 'main_champion'
        }
    }, {
        classMethods: {
            associate: function(models) {
                Summoner.belongsToMany(models.Match, {as: 'SummonerMatches', through: 'SummonerMatch'});
                Summoner.hasOne(models.RankedStats);
                Summoner.hasMany(models.RankedHistory, { as: { singular: 'RankedHistory', plural: 'RankedHistory' }});
            }
        },
        freezeTableName: true,
        underscored: true
    });


  return Summoner;
};

SummonerMatch.js

module.exports = function(sequelize, DataTypes) {
    var SummonerMatch = sequelize.define('SummonerMatch', {
        championId: {
            type: DataTypes.INTEGER,
            field: 'champion_id'
        },
        role: {
            type: DataTypes.STRING
        },
        (...)
        sightWardsBought: {
            type: DataTypes.INTEGER,
            field: 'sight_wards_bought'
        }
    }, {
        freezeTableName: true,
        underscored: true
    });

  return SummonerMatch;
};

Now I'm trying to create a new match, and associate it with a summoner, and I'm doing the following:

summoner.createSummonerMatch(matchInfo, matchDetails).then(
    function () {
        callback();
        return null;
});

Where matchInfo contains the attributes of the "Match" entity, and matchDetails contains the attributes of the "SummonerMatch" entity.

This is fine and all, but it doesn't check if the match already exists, so I'm trying to use findOrCreate here.

models.Match.findOrCreate({
    include: [ {model: models.Summoner, as: 'Participants'}],
    where: { matchId: matchInfo.matchId, server: matchInfo.server },
    defaults: {
        matchMode: queueType,
        matchDate: new Date(matchCreation),
        matchDuration: matchDurationInSeconds,
        rankedBoo: rankedBoo
        }
    }).spread(function(match, created) {
        console.log(created)
});

This almost does the trick (creates a new row in the Match table, but not in SummonerMatch). How would I proceed to insert information into SummonerMatch as well? Tried a few things (adding attributes to defaults, switching it to an array, tweaking around with the include, but no success so far.

I'm prolly missing out on something, but I can't figure out what. Any help is much appreciated :)

[EDIT] In case someone comes here looking for answers on how to do it, this works, but I'm not sure if it is the best approach:

models.Match.findOrCreate({
    include: [ {model: models.Summoner, as: 'Participants'}],
    where: { matchId: matchInfo.matchId, server: matchInfo.server },
    defaults: {
        matchMode: queueType,
        matchDate: new Date(matchCreation),
        matchDuration: matchDurationInSeconds,
        rankedBoo: rankedBoo
        }
    }).spread(function(match, created) {
        match.addParticipant(summoner, matchDetails).then(
            function () {
                console.log('Done')
            }
        )
});

It is creating a match if it doesn't exist, and adding a participant afterwards. Isn't there a way to do it all at once?

Answers:

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.