* Set the associated model. * * @param {Model} sourceInstance the source instance * @param {?Model|string|number} [associatedInstance] An persisted instance or the primary key of an instance to associate with this. Pass `null` or `undefined` to remove the association. * @param {object} [
(sourceInstance, associatedInstance, options)
| 191 | * @returns {Promise} |
| 192 | */ |
| 193 | async set(sourceInstance, associatedInstance, options) { |
| 194 | options = { ...options, scope: false }; |
| 195 | |
| 196 | const oldInstance = await sourceInstance[this.accessors.get](options); |
| 197 | // TODO Use equals method once #5605 is resolved |
| 198 | const alreadyAssociated = oldInstance && associatedInstance && this.target.primaryKeyAttributes.every(attribute => |
| 199 | oldInstance.get(attribute, { raw: true }) === (associatedInstance.get ? associatedInstance.get(attribute, { raw: true }) : associatedInstance) |
| 200 | ); |
| 201 | |
| 202 | if (oldInstance && !alreadyAssociated) { |
| 203 | oldInstance[this.foreignKey] = null; |
| 204 | |
| 205 | await oldInstance.save({ |
| 206 | ...options, |
| 207 | fields: [this.foreignKey], |
| 208 | allowNull: [this.foreignKey], |
| 209 | association: true |
| 210 | }); |
| 211 | } |
| 212 | if (associatedInstance && !alreadyAssociated) { |
| 213 | if (!(associatedInstance instanceof this.target)) { |
| 214 | const tmpInstance = {}; |
| 215 | tmpInstance[this.target.primaryKeyAttribute] = associatedInstance; |
| 216 | associatedInstance = this.target.build(tmpInstance, { |
| 217 | isNewRecord: false |
| 218 | }); |
| 219 | } |
| 220 | |
| 221 | Object.assign(associatedInstance, this.scope); |
| 222 | associatedInstance.set(this.foreignKey, sourceInstance.get(this.sourceKeyAttribute)); |
| 223 | |
| 224 | return associatedInstance.save(options); |
| 225 | } |
| 226 | |
| 227 | return null; |
| 228 | } |
| 229 | |
| 230 | /** |
| 231 | * Create a new instance of the associated model and associate it with this. |