Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

findOrCreate with include

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]}
})
like image 371
user3568719 Avatar asked Jul 04 '26 05:07

user3568719


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.

like image 114
PhilippeAuriach Avatar answered Jul 06 '26 19:07

PhilippeAuriach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!