Skip to content

Instantly share code, notes, and snippets.

@saneki
Last active August 29, 2015 14:21
Show Gist options
  • Save saneki/52c30604144adf4bd408 to your computer and use it in GitHub Desktop.
Save saneki/52c30604144adf4bd408 to your computer and use it in GitHub Desktop.
sequelize_associations_in_transaction
// sequelize
this._sequelize = new Sequelize(null, null, null, {
dialect: 'sqlite',
storage: path,
define: {
paranoid: true,
underscored: true,
underscoredAll: true
}
});
// RawrUser (unsure of a better way to deal with COLLATE NOCASE?)
var RawrUser = models.RawrUser = sequelize.define('RawrUser', {
channel: { type: Sequelize.STRING(64) + ' COLLATE NOCASE', allowNull: false },
username: { type: Sequelize.STRING(64) + ' COLLATE NOCASE', allowNull: false },
points: { type: Sequelize.INTEGER, defaultValue: 0, allowNull: false },
subpoints: { type: Sequelize.INTEGER, defaultValue: 0, allowNull: false },
remind: { type: Sequelize.BOOLEAN, defaultValue: true, allowNull: false }
}, {
instanceMethods: {
/**
* Whether or not this user has a ticket of a specific type.
* @param {String} type Ticket type to check for
*/
hasTicket: function(type) {
return this.getRawrTickets({ where: { type: type } }).then(function(tickets) {
return tickets && tickets.length > 0;
});
}
}
});
// RawrTicket
var RawrTicket = models.RawrTicket = sequelize.define('RawrTicket', {
type: { type: Sequelize.ENUM('sketch'), defaultValue: 'sketch', allowNull: false }
}, {
updatedAt: false
});
// Associations
RawrTicket.belongsTo(RawrUser);
RawrUser.hasMany(RawrTicket);
// ...
// No transaction, associations work but performing without a transaction is risky
if(user.points >= cost) {
// Update user's points
return user.update({
points: (user.points - cost)
}).then(function() {
// Add the ticket
var ticket = RawrTicket.build({
type: type,
RawrUser: user
});
return user.addRawrTicket(ticket);
});
} else {
throw new Error('Not enough points to purchase ticket');
}
// Managed Transaction, associations don't work for some reason.
// A RawrTicket will be created and inserted into the database, but with a null foreign key which
// should point to RawrUser (although when printed to console, the ticket's dataValues show the
// foreign key rawr_user_id with the expected user id)
if(user.points >= cost) {
return sequelize.transaction(function(t) {
var TRANSACTION = { transaction: t };
// Update user's points
return user.update({
points: (user.points - cost)
}, TRANSACTION).then(function() {
// Add the ticket
var ticket = RawrTicket.build({
type: type,
RawrUser: user
});
return user.addRawrTicket(ticket, TRANSACTION).then(function(ticket) {
// Only added this to print out the object with dataValues
console.log(ticket);
});
});
});
} else {
throw new Error('Not enough points to purchase ticket');
}
// As is seen in the data values, rawr_user_id seems fine and valid, but it isn't seen at all in the sql query
{ dataValues:
{ id: 5,
type: 'sketch',
rawr_user_id: 1, // A valid user id
created_at: Sun May 17 2015 03:30:13 GMT-0500 (CDT) },
_previousDataValues:
{ type: undefined,
rawr_user_id: undefined,
id: null,
points: undefined,
updated_at: undefined,
created_at: Sun May 17 2015 03:30:13 GMT-0500 (CDT) },
_changed:
{ type: true,
rawr_user_id: true,
id: true,
points: false,
updated_at: false,
created_at: false },
...
}
// The sql query log output, with the INSERT statement neglecting rawr_user_id
Executing (f5698319-44cc-4acc-a8e8-3832e1df5abe): BEGIN TRANSACTION;
Executing (f5698319-44cc-4acc-a8e8-3832e1df5abe): -- SQLite is not able to choose the isolation level REPEATABLE READ.
Executing (f5698319-44cc-4acc-a8e8-3832e1df5abe): -- SQLite does not support SET autocommit.
Executing (f5698319-44cc-4acc-a8e8-3832e1df5abe): UPDATE `rawr_users` SET `points`=50,`updated_at`='2015-05-17 08:30:13.000 +00:00' WHERE `id` = 1
Executing (f5698319-44cc-4acc-a8e8-3832e1df5abe): SELECT `id`, `type`, `created_at`, `deleted_at`, `rawr_user_id` FROM `rawr_tickets` AS `RawrTicket` WHERE (`RawrTicket`.`deleted_at` IS NULL AND (`RawrTicket`.`rawr_user_id` = 1 AND `RawrTicket`.`id` IS NULL));
Executing (f5698319-44cc-4acc-a8e8-3832e1df5abe): INSERT INTO `rawr_tickets` (`created_at`) VALUES ('2015-05-17 08:30:13.000 +00:00');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment