* Validates this instance, and if the validation passes, persists it to the database. * * Returns a Promise that resolves to the saved instance (or rejects with a `Sequelize.ValidationError`, which will have a property for each of the fields for which the validation failed, with the error mess
(options)
| 3984 | * @returns {Promise<Model>} |
| 3985 | */ |
| 3986 | async save(options) { |
| 3987 | if (arguments.length > 1) { |
| 3988 | throw new Error('The second argument was removed in favor of the options object.'); |
| 3989 | } |
| 3990 | |
| 3991 | options = Utils.cloneDeep(options); |
| 3992 | |
| 3993 | // Add CLS transaction |
| 3994 | if (options.transaction === undefined && this.sequelize.constructor._cls) { |
| 3995 | const t = this.sequelize.constructor._cls.get('transaction'); |
| 3996 | if (t) { |
| 3997 | options.transaction = t; |
| 3998 | } |
| 3999 | } |
| 4000 | |
| 4001 | options = _.defaults(options, { |
| 4002 | hooks: true, |
| 4003 | validate: true |
| 4004 | }); |
| 4005 | |
| 4006 | if (!options.fields) { |
| 4007 | if (this.isNewRecord) { |
| 4008 | options.fields = Object.keys(this.constructor.rawAttributes); |
| 4009 | } else { |
| 4010 | options.fields = _.intersection(this.changed(), Object.keys(this.constructor.rawAttributes)); |
| 4011 | } |
| 4012 | |
| 4013 | options.defaultFields = options.fields; |
| 4014 | } |
| 4015 | |
| 4016 | if (options.returning === undefined) { |
| 4017 | if (options.association) { |
| 4018 | options.returning = false; |
| 4019 | } else if (this.isNewRecord) { |
| 4020 | options.returning = true; |
| 4021 | } |
| 4022 | } |
| 4023 | |
| 4024 | const primaryKeyName = this.constructor.primaryKeyAttribute; |
| 4025 | const primaryKeyAttribute = primaryKeyName && this.constructor.rawAttributes[primaryKeyName]; |
| 4026 | const createdAtAttr = this.constructor._timestampAttributes.createdAt; |
| 4027 | const versionAttr = this.constructor._versionAttribute; |
| 4028 | const hook = this.isNewRecord ? 'Create' : 'Update'; |
| 4029 | const wasNewRecord = this.isNewRecord; |
| 4030 | const now = Utils.now(this.sequelize.options.dialect); |
| 4031 | let updatedAtAttr = this.constructor._timestampAttributes.updatedAt; |
| 4032 | |
| 4033 | if (updatedAtAttr && options.fields.length > 0 && !options.fields.includes(updatedAtAttr)) { |
| 4034 | options.fields.push(updatedAtAttr); |
| 4035 | } |
| 4036 | if (versionAttr && options.fields.length > 0 && !options.fields.includes(versionAttr)) { |
| 4037 | options.fields.push(versionAttr); |
| 4038 | } |
| 4039 | |
| 4040 | if (options.silent === true && !(this.isNewRecord && this.get(updatedAtAttr, { raw: true }))) { |
| 4041 | // UpdateAtAttr might have been added as a result of Object.keys(Model.rawAttributes). In that case we have to remove it again |
| 4042 | _.remove(options.fields, val => val === updatedAtAttr); |
| 4043 | updatedAtAttr = false; |