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