* Delete multiple instances, or set their deletedAt timestamp to the current time if `paranoid` is enabled. * * @param {object} options destroy options * @param {object} [options.where] Filter the destroy * @param {boolean} [opt
(options)
| 2916 | * @returns {Promise<number>} The number of destroyed rows |
| 2917 | */ |
| 2918 | static async destroy(options) { |
| 2919 | options = Utils.cloneDeep(options); |
| 2920 | |
| 2921 | this._injectScope(options); |
| 2922 | |
| 2923 | if (!options || !(options.where || options.truncate)) { |
| 2924 | throw new Error('Missing where or truncate attribute in the options parameter of model.destroy.'); |
| 2925 | } |
| 2926 | |
| 2927 | if (!options.truncate && !_.isPlainObject(options.where) && !Array.isArray(options.where) && !(options.where instanceof Utils.SequelizeMethod)) { |
| 2928 | throw new Error('Expected plain object, array or sequelize method in the options.where parameter of model.destroy.'); |
| 2929 | } |
| 2930 | |
| 2931 | options = _.defaults(options, { |
| 2932 | hooks: true, |
| 2933 | individualHooks: false, |
| 2934 | force: false, |
| 2935 | cascade: false, |
| 2936 | restartIdentity: false |
| 2937 | }); |
| 2938 | |
| 2939 | options.type = QueryTypes.BULKDELETE; |
| 2940 | |
| 2941 | Utils.mapOptionFieldNames(options, this); |
| 2942 | options.model = this; |
| 2943 | |
| 2944 | |
| 2945 | // Run before hook |
| 2946 | if (options.hooks) { |
| 2947 | await this.runHooks('beforeBulkDestroy', options); |
| 2948 | } |
| 2949 | let instances; |
| 2950 | // Get daos and run beforeDestroy hook on each record individually |
| 2951 | if (options.individualHooks) { |
| 2952 | instances = await this.findAll({ where: options.where, transaction: options.transaction, logging: options.logging, benchmark: options.benchmark }); |
| 2953 | |
| 2954 | await Promise.all(instances.map(instance => this.runHooks('beforeDestroy', instance, options))); |
| 2955 | } |
| 2956 | let result; |
| 2957 | // Run delete query (or update if paranoid) |
| 2958 | if (this._timestampAttributes.deletedAt && !options.force) { |
| 2959 | // Set query type appropriately when running soft delete |
| 2960 | options.type = QueryTypes.BULKUPDATE; |
| 2961 | |
| 2962 | const attrValueHash = {}; |
| 2963 | const deletedAtAttribute = this.rawAttributes[this._timestampAttributes.deletedAt]; |
| 2964 | const field = this.rawAttributes[this._timestampAttributes.deletedAt].field; |
| 2965 | const where = { |
| 2966 | [field]: Object.prototype.hasOwnProperty.call(deletedAtAttribute, 'defaultValue') ? deletedAtAttribute.defaultValue : null |
| 2967 | }; |
| 2968 | |
| 2969 | |
| 2970 | attrValueHash[field] = Utils.now(this.sequelize.options.dialect); |
| 2971 | result = await this.queryInterface.bulkUpdate(this.getTableName(options), attrValueHash, Object.assign(where, options.where), options, this.rawAttributes); |
| 2972 | } else { |
| 2973 | result = await this.queryInterface.bulkDelete(this.getTableName(options), options.where, options, this); |
| 2974 | } |
| 2975 | // Run afterDestroy hook on each record individually |