Last active
December 17, 2020 04:59
-
-
Save navsqi/3a02089dd5dddeea46c21c244cddbe94 to your computer and use it in GitHub Desktop.
Sequelize guide examples.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict'; | |
| module.exports = { | |
| up: async (queryInterface, Sequelize) => { | |
| await queryInterface.createTable('stores', { | |
| id: { | |
| allowNull: false, | |
| autoIncrement: true, | |
| primaryKey: true, | |
| type: Sequelize.INTEGER | |
| }, | |
| storeCode: { | |
| type: Sequelize.STRING | |
| }, | |
| storeName: { | |
| type: Sequelize.STRING | |
| }, | |
| createdAt: { | |
| allowNull: false, | |
| type: Sequelize.DATE | |
| }, | |
| updatedAt: { | |
| allowNull: false, | |
| type: Sequelize.DATE | |
| } | |
| }); | |
| }, | |
| down: async (queryInterface, Sequelize) => { | |
| await queryInterface.dropTable('stores'); | |
| } | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict'; | |
| module.exports = { | |
| up: async (queryInterface, Sequelize) => { | |
| await queryInterface.createTable('Users', { | |
| id: { | |
| allowNull: false, | |
| autoIncrement: true, | |
| primaryKey: true, | |
| type: Sequelize.INTEGER, | |
| }, | |
| storeId: { | |
| type: Sequelize.INTEGER, | |
| references: { | |
| model: 'stores', | |
| id: 'id', | |
| }, | |
| onUpdate: 'CASCADE', | |
| onDelete: 'CASCADE', | |
| }, | |
| email: { | |
| type: Sequelize.STRING, | |
| }, | |
| password: { | |
| type: Sequelize.STRING, | |
| }, | |
| role: { | |
| type: Sequelize.STRING, | |
| }, | |
| active: { | |
| type: Sequelize.BOOLEAN, | |
| }, | |
| dueDate: { | |
| allowNull: false, | |
| type: Sequelize.DATEONLY, | |
| }, | |
| createdAt: { | |
| allowNull: false, | |
| type: Sequelize.DATE, | |
| }, | |
| updatedAt: { | |
| allowNull: false, | |
| type: Sequelize.DATE, | |
| }, | |
| }); | |
| }, | |
| down: async (queryInterface, Sequelize) => { | |
| await queryInterface.dropTable('Users'); | |
| }, | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict'; | |
| const { Model } = require('sequelize'); | |
| module.exports = (sequelize, DataTypes) => { | |
| class store extends Model { | |
| /** | |
| * Helper method for defining associations. | |
| * This method is not a part of Sequelize lifecycle. | |
| * The `models/index` file will call this method automatically. | |
| */ | |
| static associate(models) { | |
| store.hasMany(models.user, { | |
| as: 'users', | |
| }); | |
| } | |
| } | |
| store.init( | |
| { | |
| storeCode: { | |
| type: DataTypes.STRING, | |
| allowNull: false, | |
| validate: { | |
| notEmpty: true, | |
| notNull: { | |
| msg: 'Please enter your store code', | |
| }, | |
| }, | |
| }, | |
| storeName: { | |
| type: DataTypes.STRING, | |
| allowNull: false, | |
| validate: { | |
| notEmpty: true, | |
| notNull: { | |
| msg: 'Please enter your store name', | |
| }, | |
| }, | |
| }, | |
| }, | |
| { | |
| sequelize, | |
| modelName: 'store', | |
| } | |
| ); | |
| return store; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict'; | |
| const { Model } = require('sequelize'); | |
| module.exports = (sequelize, DataTypes) => { | |
| class user extends Model { | |
| /** | |
| * Helper method for defining associations. | |
| * This method is not a part of Sequelize lifecycle. | |
| * The `models/index` file will call this method automatically. | |
| */ | |
| static associate(models) { | |
| user.hasMany(models.addressbook, { as: 'addressBooks' }); | |
| user.hasMany(models.shippingorder, { as: 'shippingOrders' }); | |
| user.belongsTo(models.store, { | |
| foreignKey: 'storeId', | |
| as: 'store', | |
| }); | |
| user.hasMany(models.productorder, { as: 'productOrders' }); | |
| } | |
| } | |
| user.init( | |
| { | |
| storeId: { | |
| type: DataTypes.NUMBER, | |
| }, | |
| email: { | |
| type: DataTypes.STRING, | |
| validate: { | |
| isEmail: { | |
| args: true, | |
| msg: 'Provide a valid email address', | |
| }, | |
| }, | |
| }, | |
| password: DataTypes.STRING, | |
| role: { | |
| type: DataTypes.STRING, | |
| defaultValue: 'user', | |
| }, | |
| active: { | |
| type: DataTypes.BOOLEAN, | |
| defaultValue: 1, | |
| }, | |
| dueDate: DataTypes.DATE | |
| }, | |
| { | |
| sequelize, | |
| modelName: 'user', | |
| } | |
| ); | |
| return user; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Method 1 via the .init() method | |
| class User extends Model {} | |
| User.init({ | |
| username: DataTypes.STRING, | |
| mood: { | |
| type: DataTypes.ENUM, | |
| values: ['happy', 'sad', 'neutral'] | |
| } | |
| }, { | |
| hooks: { | |
| beforeValidate: (user, options) => { | |
| user.mood = 'happy'; | |
| }, | |
| afterValidate: (user, options) => { | |
| user.username = 'Toni'; | |
| } | |
| }, | |
| sequelize | |
| }); | |
| // Method 2 via the .addHook() method | |
| User.addHook('beforeValidate', (user, options) => { | |
| user.mood = 'happy'; | |
| }); | |
| User.addHook('afterValidate', 'someCustomName', (user, options) => { | |
| return Promise.reject(new Error("I'm afraid I can't let you do that!")); | |
| }); | |
| // Method 3 via the direct method | |
| User.beforeCreate(async (user, options) => { | |
| const hashedPassword = await hashPassword(user.password); | |
| user.password = hashedPassword; | |
| }); | |
| User.afterValidate('myHookAfter', (user, options) => { | |
| user.username = 'Toni'; | |
| }); | |
| // ======================== Examples ======================== | |
| class payment extends Model {} | |
| payment.init(...); | |
| payment.addHook('beforeCreate', (payment, options) => { | |
| let d = new Date(); | |
| let date = `${d.getDate()}`; | |
| let m = `${d.getMonth() + 1}`; | |
| let y = `${d.getFullYear()}`; | |
| let dmy = `${date.padStart(2, 0)}${m.padStart(2, 0)}${y.substr(-2)}`; | |
| payment.id = `DEL-${dmy}-${cryptoRandomString({ | |
| length: 6, | |
| type: 'numeric', | |
| })}`; | |
| }); | |
| return payment; | |
| // ============================== | |
| class productimage extends Model {} | |
| productimage.init(...); | |
| productimage.addHook('beforeBulkDestroy', async (options) => { | |
| const productImage = await options.model.findByPk(options.where.id); | |
| deleteFileImage(productImage.image, 'product'); | |
| return true; | |
| }); | |
| return productimage; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==== Unmanaged Transactions ==== | |
| // First, we start a transaction and save it into a variable | |
| const t = await sequelize.transaction(); | |
| try { | |
| // Then, we do some calls passing this transaction as an option: | |
| const user = await User.create({ | |
| firstName: 'Bart', | |
| lastName: 'Simpson' | |
| }, { transaction: t }); | |
| await user.addSibling({ | |
| firstName: 'Lisa', | |
| lastName: 'Simpson' | |
| }, { transaction: t }); | |
| // If the execution reaches this line, no errors were thrown. | |
| // We commit the transaction. | |
| await t.commit(); | |
| } catch (error) { | |
| // If the execution reaches this line, an error was thrown. | |
| // We rollback the transaction. | |
| await t.rollback(); | |
| } | |
| // ==== Managed Transactions ==== | |
| try { | |
| const result = await sequelize.transaction(async (t) => { | |
| const user = await User.create({ | |
| firstName: 'Abraham', | |
| lastName: 'Lincoln' | |
| }, { transaction: t }); | |
| await user.setShooter({ | |
| firstName: 'John', | |
| lastName: 'Boothe' | |
| }, { transaction: t }); | |
| return user; | |
| }); | |
| // If the execution reaches this line, the transaction has been committed successfully | |
| // `result` is whatever was returned from the transaction callback (the `user`, in this case) | |
| } catch (error) { | |
| // If the execution reaches this line, an error occurred. | |
| // The transaction has already been rolled back automatically by Sequelize! | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Generate custom ID | |
| // Example: DREAM-010920-0001 | |
| // db = require('../models/index'); | |
| exports.generateId = async (db, prefix, tableName) => { | |
| let d = new Date(); | |
| let date = `${d.getDate()}`; | |
| let m = `${d.getMonth() + 1}`; | |
| let y = `${d.getFullYear()}`; | |
| let dmy = `${date.padStart(2, 0)}${m.padStart(2, 0)}${y.substr(-2)}`; | |
| let masterQuery = await db.sequelize.query( | |
| `SELECT RIGHT(id,4) as data FROM ${tableName} WHERE id LIKE "${prefix}-${dmy}%" ORDER BY id DESC LIMIT 1`, | |
| { | |
| type: db.sequelize.QueryTypes.SELECT, | |
| } | |
| ); | |
| let count = '1'; | |
| let customId; | |
| if (masterQuery.length > 0) { | |
| count = `${Number(masterQuery[0].data) + 1}`; | |
| customId = `${prefix}-${dmy}-${count.padStart(4, '0')}`; | |
| } else { | |
| customId = `${prefix}-${dmy}-${count.padStart(4, '0')}`; | |
| } | |
| return customId; | |
| }; | |
| // Parse JSON | |
| exports.jsonParse = (data) => { | |
| return JSON.parse(JSON.stringify(data)); | |
| }; | |
| // Pagination | |
| exports.pagination = (req) => { | |
| const limitQ = req.query.limit ? { limit: Number(req.query.limit) } : false; | |
| const page = req.query.page | |
| ? { page: Number(req.query.page) > 0 ? Number(req.query.page) : 1 } | |
| : false; | |
| const offsetQ = page | |
| ? { offset: (Number(req.query.page) - 1) * Number(req.query.limit) } | |
| : false; | |
| const orderQ = req.query.order ? req.query.order.split(':') : false; | |
| const order = { order: [orderQ ? [orderQ[0], orderQ[1]] : ['id', 'DESC']] }; | |
| return { ...limitQ, ...offsetQ, ...order }; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var Bar = sequelize.define('Bar', { /* bla */ }, { | |
| // don't add the timestamp attributes (updatedAt, createdAt) | |
| timestamps: false, | |
| // don't delete database entries but set the newly added attribute deletedAt | |
| // to the current date (when deletion was done). paranoid will only work if | |
| // timestamps are enabled | |
| paranoid: true, | |
| // don't use camelcase for automatically added attributes but underscore style | |
| // so updatedAt will be updated_at | |
| underscored: true, | |
| // disable the modification of tablenames; By default, sequelize will automatically | |
| // transform all passed model names (first parameter of define) into plural. | |
| // if you don't want that, set the following | |
| freezeTableName: true, | |
| // define the table's name | |
| tableName: 'my_very_custom_table_name' | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment