findOrCreate with include - sequelize.js

Viewed 1166

I want to create a Tournament (if not exists), and a Match (if not exists) associated to the Tournament.

let [match, created] = await Match.findOrCreate( {
  where: {scoreHome: 97, Tournament: {name: "USA South Men's Basketball"}}, 
  include: [Tournament]
})

If the tournament 'USA South Men's Basketball' is already in the db (let's say with id 1), then the match should be created with TournamentId: 1. If there is already a match in the db with {scoreHome: 97 and TournamentId: 1}, then no match should be created.

  let Match = sequelize.define('Match', {
    scoreHome: DataTypes.INTEGER,
    //...
  })

  Match.associate = models => {
    Match.belongsTo(models.Tournament)
  }

EDIT Here is the error:

[Error: Invalid value [object Object]]

This works fine

let match = await Match.create({
    scoreHome: 97, Tournament: {name: "USA South Men's Basketball"}
  },{include: [Tournament]}
})
1 Answers

I am not sure sequelize will allow this "deep findOrCreate". But you can achieve the wanted effect using two queries, and the sequelize transaction to make sure the two are linked together:

const t = await sequelize.transaction();

try {
  const [tournament] = await Tournament.findOrCreate({
    where: {name: "USA South Men's Basketball"},
    { transaction: t }
  })
  const [match] = await Match.findOrCreate({
    where: {scoreHome: 97, tournamentId: tournament.id},
    { transaction: t }
  })
  t.commit()
} catch(err) {
  t.rollback()
}

It is a bit more verbose, but with this you are sure of what you do, and it is also (personal opinion) more readable for another dev reading that after you.

Related