Monday 29 February 2016

Sequelize - findOrCreate on the "through" table, on belongsToMany association

Hello all,First of all, I'm rather new to Node.JS and even newer to Sequelize, so appologies if the question seems rather dumb or I'm making stupid mistake :)I have the following Model entities:Match.jsmodule.exports = function(sequelize, DataTypes) { var Match = sequelize.define('Match', { matchId: { type: DataTypes.BIGINT, field: 'match_id' }, server: { type: DataTypes.STRING }, matchMode: { type: DataTypes.STRING, field: 'match_mode' }, matchDate: { type: DataTypes.DATE, field: 'match_date' }, matchDuration: { type: DataTypes.INTEGER, field: 'match_duration' }, 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.jsmodule.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.jsmodule.exports = function(sequelize, DataTypes) { var SummonerMatch = sequelize.define('SummonerMatch', { championId: { type: DataTypes.INTEGER, field: 'champion_id' }, role: { type: DataTypes.STRING }, winnerBoo: { type: DataTypes.BOOLEAN, field: 'winner_boo' }, kills: { type: DataTypes.INTEGER }, deaths: { type: DataTypes.INTEGER }, assists: { type: DataTypes.INTEGER }, championLevel: { type: DataTypes.INTEGER, field: 'champion_level' }, goldEarned: { type: DataTypes.INTEGER, field: 'gold_earned' }, item0: { type: DataTypes.INTEGER, field: 'item_0' }, item1: { type: DataTypes.INTEGER, field: 'item_1' }, item2: { type: DataTypes.INTEGER, field: 'item_2' }, item3: { type: DataTypes.INTEGER, field: 'item_3' }, item4: { type: DataTypes.INTEGER, field: 'item_4' }, item5: { type: DataTypes.INTEGER, field: 'item_5' }, item6: { type: DataTypes.INTEGER, field: 'item_6' }, summonerSpell1: { type: DataTypes.INTEGER, field: 'summoner_spell_1' }, summonerSpell2: { type: DataTypes.INTEGER, field: 'summoner_spell_2' }, largestKillingSpree: { type: DataTypes.INTEGER, field: 'largest_killing_spree' }, largestMultiKill: { type: DataTypes.INTEGER, field: 'largest_multi_kill' }, magicDamageDealt: { type: DataTypes.INTEGER, field: 'magic_damage_dealt' }, magicDamageDealtToChampions: { type: DataTypes.INTEGER, field: 'magic_damage_dealt_to_champions' }, magicDamageTaken: { type: DataTypes.INTEGER, field: 'magic_damage_taken' }, physicalDamageDealt: { type: DataTypes.INTEGER, field: 'physical_damage_dealt' }, physicalDamageDealtToChampions: { type: DataTypes.INTEGER, field: 'physical_damage_dealt_to_champions' }, physicalDamageTaken: { type: DataTypes.INTEGER, field: 'physical_damage_taken' }, trueDamageDealt: { type: DataTypes.INTEGER, field: 'true_damage_dealt' }, trueDamageDealtToChampions: { type: DataTypes.INTEGER, field: 'true_damage_dealt_to_champions' }, trueDamageTaken: { type: DataTypes.INTEGER, field: 'true_damage_taken' }, minionsKilled: { type: DataTypes.INTEGER, field: 'minions_killed' }, neutralMinionsKilled: { type: DataTypes.INTEGER, field: 'neutral_minions_killed' }, visionWardsBought: { type: DataTypes.INTEGER, field: 'vision_wards_bought' }, 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:] Formatting :)

Submitted February 29, 2016 at 06:31PM by Pain5Q

No comments:

Post a Comment