I'm currently brute-forcing this, but am confident there is a better solution that uses Sequelize, the code in question (using postgres):
...
then((tile_data) => {
return Encounter.findAll({
where: {
level: tile_data.dataValues.level
},
transaction: transaction_data
}).then((encounter_data) => {
let encounter = encounter_data[Math.floor((Math.random() * encounter_data.length))].dataValues
return Battle.create({
character_id: character_data.dataValues.id,
encounter_id: encounter.id,
encounter_hp: encounter.max_hp,
encounter_mana: encounter.max_mana
}, {
transaction: transaction_data
})
...
Aside from seeming 'ugly', with this code I am loading all ENCOUNTERS into memory just to pluck one element out of the array.
Does anyone know how to do this through Sequelize, ideally without using a raw query?
Thank you
You can try this :
Encounter.findAll({ order: Sequelize.literal('rand()'), limit: 5 }).then((encounters) => {
// single random encounter
});
Don't forget to require the Sequelize 👌
I think this solution is the most clear one. You should use a random function from a sequelize instance
const sequelize = new Sequelize(url, opts);
Recommend to use a sequelize-cli to generate initial schema, it automatically exports sequelize variable.
Encounter.findOne({
order: sequelize.random()
});
Also with this approach u don't need to solve RAND() vs RANDOM() problem if you change a db dialect from postgres to MySQL or back.
Encounter.findOne({ order: 'random()' }).then((encounter) => {
// single random encounter
});
random() should be used in case of PostgreSQL, in case of MySQL you would probably use rand(). You did not specify what database are you using.
Edit
Or if you really want to use .findAll():
Encounter.findAll({ order: 'random()', limit: 1 }).then((encounter) => {
// single random encounter
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With