belongs-to-many.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __defProps = Object.defineProperties;
  4. var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
  5. var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  6. var __hasOwnProp = Object.prototype.hasOwnProperty;
  7. var __propIsEnum = Object.prototype.propertyIsEnumerable;
  8. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  9. var __spreadValues = (a, b) => {
  10. for (var prop in b || (b = {}))
  11. if (__hasOwnProp.call(b, prop))
  12. __defNormalProp(a, prop, b[prop]);
  13. if (__getOwnPropSymbols)
  14. for (var prop of __getOwnPropSymbols(b)) {
  15. if (__propIsEnum.call(b, prop))
  16. __defNormalProp(a, prop, b[prop]);
  17. }
  18. return a;
  19. };
  20. var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
  21. const Utils = require("./../utils");
  22. const Helpers = require("./helpers");
  23. const _ = require("lodash");
  24. const Association = require("./base");
  25. const BelongsTo = require("./belongs-to");
  26. const HasMany = require("./has-many");
  27. const HasOne = require("./has-one");
  28. const AssociationError = require("../errors").AssociationError;
  29. const EmptyResultError = require("../errors").EmptyResultError;
  30. const Op = require("../operators");
  31. class BelongsToMany extends Association {
  32. constructor(source, target, options) {
  33. super(source, target, options);
  34. if (this.options.through === void 0 || this.options.through === true || this.options.through === null) {
  35. throw new AssociationError(`${source.name}.belongsToMany(${target.name}) requires through option, pass either a string or a model`);
  36. }
  37. if (!this.options.through.model) {
  38. this.options.through = {
  39. model: options.through
  40. };
  41. }
  42. this.associationType = "BelongsToMany";
  43. this.targetAssociation = null;
  44. this.sequelize = source.sequelize;
  45. this.through = __spreadValues({}, this.options.through);
  46. this.isMultiAssociation = true;
  47. this.doubleLinked = false;
  48. if (!this.as && this.isSelfAssociation) {
  49. throw new AssociationError("'as' must be defined for many-to-many self-associations");
  50. }
  51. if (this.as) {
  52. this.isAliased = true;
  53. if (_.isPlainObject(this.as)) {
  54. this.options.name = this.as;
  55. this.as = this.as.plural;
  56. } else {
  57. this.options.name = {
  58. plural: this.as,
  59. singular: Utils.singularize(this.as)
  60. };
  61. }
  62. } else {
  63. this.as = this.target.options.name.plural;
  64. this.options.name = this.target.options.name;
  65. }
  66. this.combinedTableName = Utils.combineTableNames(this.source.tableName, this.isSelfAssociation ? this.as || this.target.tableName : this.target.tableName);
  67. if (this.isSelfAssociation) {
  68. this.targetAssociation = this;
  69. }
  70. _.each(this.target.associations, (association) => {
  71. if (association.associationType !== "BelongsToMany")
  72. return;
  73. if (association.target !== this.source)
  74. return;
  75. if (this.options.through.model === association.options.through.model) {
  76. this.paired = association;
  77. association.paired = this;
  78. }
  79. });
  80. this.sourceKey = this.options.sourceKey || this.source.primaryKeyAttribute;
  81. this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
  82. if (this.options.targetKey) {
  83. this.targetKey = this.options.targetKey;
  84. this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
  85. } else {
  86. this.targetKeyDefault = true;
  87. this.targetKey = this.target.primaryKeyAttribute;
  88. this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
  89. }
  90. this._createForeignAndOtherKeys();
  91. if (typeof this.through.model === "string") {
  92. if (!this.sequelize.isDefined(this.through.model)) {
  93. this.through.model = this.sequelize.define(this.through.model, {}, Object.assign(this.options, {
  94. tableName: this.through.model,
  95. indexes: [],
  96. paranoid: this.through.paranoid ? this.through.paranoid : false,
  97. validate: {}
  98. }));
  99. } else {
  100. this.through.model = this.sequelize.model(this.through.model);
  101. }
  102. }
  103. Object.assign(this.options, _.pick(this.through.model.options, [
  104. "timestamps",
  105. "createdAt",
  106. "updatedAt",
  107. "deletedAt",
  108. "paranoid"
  109. ]));
  110. if (this.paired) {
  111. let needInjectPaired = false;
  112. if (this.targetKeyDefault) {
  113. this.targetKey = this.paired.sourceKey;
  114. this.targetKeyField = this.paired.sourceKeyField;
  115. this._createForeignAndOtherKeys();
  116. }
  117. if (this.paired.targetKeyDefault) {
  118. if (this.paired.targetKey !== this.sourceKey) {
  119. delete this.through.model.rawAttributes[this.paired.otherKey];
  120. this.paired.targetKey = this.sourceKey;
  121. this.paired.targetKeyField = this.sourceKeyField;
  122. this.paired._createForeignAndOtherKeys();
  123. needInjectPaired = true;
  124. }
  125. }
  126. if (this.otherKeyDefault) {
  127. this.otherKey = this.paired.foreignKey;
  128. }
  129. if (this.paired.otherKeyDefault) {
  130. if (this.paired.otherKey !== this.foreignKey) {
  131. delete this.through.model.rawAttributes[this.paired.otherKey];
  132. this.paired.otherKey = this.foreignKey;
  133. needInjectPaired = true;
  134. }
  135. }
  136. if (needInjectPaired) {
  137. this.paired._injectAttributes();
  138. }
  139. }
  140. if (this.through) {
  141. this.throughModel = this.through.model;
  142. }
  143. this.options.tableName = this.combinedName = this.through.model === Object(this.through.model) ? this.through.model.tableName : this.through.model;
  144. this.associationAccessor = this.as;
  145. const plural = _.upperFirst(this.options.name.plural);
  146. const singular = _.upperFirst(this.options.name.singular);
  147. this.accessors = {
  148. get: `get${plural}`,
  149. set: `set${plural}`,
  150. addMultiple: `add${plural}`,
  151. add: `add${singular}`,
  152. create: `create${singular}`,
  153. remove: `remove${singular}`,
  154. removeMultiple: `remove${plural}`,
  155. hasSingle: `has${singular}`,
  156. hasAll: `has${plural}`,
  157. count: `count${plural}`
  158. };
  159. }
  160. _createForeignAndOtherKeys() {
  161. if (_.isObject(this.options.foreignKey)) {
  162. this.foreignKeyAttribute = this.options.foreignKey;
  163. this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
  164. } else {
  165. this.foreignKeyAttribute = {};
  166. this.foreignKey = this.options.foreignKey || Utils.camelize([
  167. this.source.options.name.singular,
  168. this.sourceKey
  169. ].join("_"));
  170. }
  171. if (_.isObject(this.options.otherKey)) {
  172. this.otherKeyAttribute = this.options.otherKey;
  173. this.otherKey = this.otherKeyAttribute.name || this.otherKeyAttribute.fieldName;
  174. } else {
  175. if (!this.options.otherKey) {
  176. this.otherKeyDefault = true;
  177. }
  178. this.otherKeyAttribute = {};
  179. this.otherKey = this.options.otherKey || Utils.camelize([
  180. this.isSelfAssociation ? Utils.singularize(this.as) : this.target.options.name.singular,
  181. this.targetKey
  182. ].join("_"));
  183. }
  184. }
  185. _injectAttributes() {
  186. this.identifier = this.foreignKey;
  187. this.foreignIdentifier = this.otherKey;
  188. _.each(this.through.model.rawAttributes, (attribute, attributeName) => {
  189. if (attribute.primaryKey === true && attribute._autoGenerated === true) {
  190. if ([this.foreignKey, this.otherKey].includes(attributeName)) {
  191. attribute.primaryKey = false;
  192. } else {
  193. delete this.through.model.rawAttributes[attributeName];
  194. }
  195. this.primaryKeyDeleted = true;
  196. }
  197. });
  198. const sourceKey = this.source.rawAttributes[this.sourceKey];
  199. const sourceKeyType = sourceKey.type;
  200. const sourceKeyField = this.sourceKeyField;
  201. const targetKey = this.target.rawAttributes[this.targetKey];
  202. const targetKeyType = targetKey.type;
  203. const targetKeyField = this.targetKeyField;
  204. const sourceAttribute = __spreadValues({ type: sourceKeyType }, this.foreignKeyAttribute);
  205. const targetAttribute = __spreadValues({ type: targetKeyType }, this.otherKeyAttribute);
  206. if (this.primaryKeyDeleted === true) {
  207. targetAttribute.primaryKey = sourceAttribute.primaryKey = true;
  208. } else if (this.through.unique !== false) {
  209. let uniqueKey;
  210. if (typeof this.options.uniqueKey === "string" && this.options.uniqueKey !== "") {
  211. uniqueKey = this.options.uniqueKey;
  212. } else {
  213. uniqueKey = [this.through.model.tableName, this.foreignKey, this.otherKey, "unique"].join("_");
  214. }
  215. targetAttribute.unique = sourceAttribute.unique = uniqueKey;
  216. }
  217. if (!this.through.model.rawAttributes[this.foreignKey]) {
  218. this.through.model.rawAttributes[this.foreignKey] = {
  219. _autoGenerated: true
  220. };
  221. }
  222. if (!this.through.model.rawAttributes[this.otherKey]) {
  223. this.through.model.rawAttributes[this.otherKey] = {
  224. _autoGenerated: true
  225. };
  226. }
  227. if (this.options.constraints !== false) {
  228. sourceAttribute.references = {
  229. model: this.source.getTableName(),
  230. key: sourceKeyField
  231. };
  232. sourceAttribute.onDelete = this.options.onDelete || this.through.model.rawAttributes[this.foreignKey].onDelete;
  233. sourceAttribute.onUpdate = this.options.onUpdate || this.through.model.rawAttributes[this.foreignKey].onUpdate;
  234. if (!sourceAttribute.onDelete)
  235. sourceAttribute.onDelete = "CASCADE";
  236. if (!sourceAttribute.onUpdate)
  237. sourceAttribute.onUpdate = "CASCADE";
  238. targetAttribute.references = {
  239. model: this.target.getTableName(),
  240. key: targetKeyField
  241. };
  242. targetAttribute.onDelete = this.through.model.rawAttributes[this.otherKey].onDelete || this.options.onDelete;
  243. targetAttribute.onUpdate = this.through.model.rawAttributes[this.otherKey].onUpdate || this.options.onUpdate;
  244. if (!targetAttribute.onDelete)
  245. targetAttribute.onDelete = "CASCADE";
  246. if (!targetAttribute.onUpdate)
  247. targetAttribute.onUpdate = "CASCADE";
  248. }
  249. Object.assign(this.through.model.rawAttributes[this.foreignKey], sourceAttribute);
  250. Object.assign(this.through.model.rawAttributes[this.otherKey], targetAttribute);
  251. this.through.model.refreshAttributes();
  252. this.identifierField = this.through.model.rawAttributes[this.foreignKey].field || this.foreignKey;
  253. this.foreignIdentifierField = this.through.model.rawAttributes[this.otherKey].field || this.otherKey;
  254. if (this.options.sequelize.options.dialect === "db2" && this.source.rawAttributes[this.sourceKey].primaryKey !== true) {
  255. this.source.rawAttributes[this.sourceKey].unique = true;
  256. }
  257. if (this.paired && !this.paired.foreignIdentifierField) {
  258. this.paired.foreignIdentifierField = this.through.model.rawAttributes[this.paired.otherKey].field || this.paired.otherKey;
  259. }
  260. this.toSource = new BelongsTo(this.through.model, this.source, {
  261. foreignKey: this.foreignKey
  262. });
  263. this.manyFromSource = new HasMany(this.source, this.through.model, {
  264. foreignKey: this.foreignKey
  265. });
  266. this.oneFromSource = new HasOne(this.source, this.through.model, {
  267. foreignKey: this.foreignKey,
  268. sourceKey: this.sourceKey,
  269. as: this.through.model.name
  270. });
  271. this.toTarget = new BelongsTo(this.through.model, this.target, {
  272. foreignKey: this.otherKey
  273. });
  274. this.manyFromTarget = new HasMany(this.target, this.through.model, {
  275. foreignKey: this.otherKey
  276. });
  277. this.oneFromTarget = new HasOne(this.target, this.through.model, {
  278. foreignKey: this.otherKey,
  279. sourceKey: this.targetKey,
  280. as: this.through.model.name
  281. });
  282. if (this.paired && this.paired.otherKeyDefault) {
  283. this.paired.toTarget = new BelongsTo(this.paired.through.model, this.paired.target, {
  284. foreignKey: this.paired.otherKey
  285. });
  286. this.paired.oneFromTarget = new HasOne(this.paired.target, this.paired.through.model, {
  287. foreignKey: this.paired.otherKey,
  288. sourceKey: this.paired.targetKey,
  289. as: this.paired.through.model.name
  290. });
  291. }
  292. Helpers.checkNamingCollision(this);
  293. return this;
  294. }
  295. mixin(obj) {
  296. const methods = ["get", "count", "hasSingle", "hasAll", "set", "add", "addMultiple", "remove", "removeMultiple", "create"];
  297. const aliases = {
  298. hasSingle: "has",
  299. hasAll: "has",
  300. addMultiple: "add",
  301. removeMultiple: "remove"
  302. };
  303. Helpers.mixinMethods(this, obj, methods, aliases);
  304. }
  305. async get(instance, options) {
  306. options = Utils.cloneDeep(options) || {};
  307. const through = this.through;
  308. let scopeWhere;
  309. let throughWhere;
  310. if (this.scope) {
  311. scopeWhere = __spreadValues({}, this.scope);
  312. }
  313. options.where = {
  314. [Op.and]: [
  315. scopeWhere,
  316. options.where
  317. ]
  318. };
  319. if (Object(through.model) === through.model) {
  320. throughWhere = {};
  321. throughWhere[this.foreignKey] = instance.get(this.sourceKey);
  322. if (through.scope) {
  323. Object.assign(throughWhere, through.scope);
  324. }
  325. if (options.through && options.through.where) {
  326. throughWhere = {
  327. [Op.and]: [throughWhere, options.through.where]
  328. };
  329. }
  330. options.include = options.include || [];
  331. options.include.push({
  332. association: this.oneFromTarget,
  333. attributes: options.joinTableAttributes,
  334. required: true,
  335. paranoid: _.get(options.through, "paranoid", true),
  336. where: throughWhere
  337. });
  338. }
  339. let model = this.target;
  340. if (Object.prototype.hasOwnProperty.call(options, "scope")) {
  341. if (!options.scope) {
  342. model = model.unscoped();
  343. } else {
  344. model = model.scope(options.scope);
  345. }
  346. }
  347. if (Object.prototype.hasOwnProperty.call(options, "schema")) {
  348. model = model.schema(options.schema, options.schemaDelimiter);
  349. }
  350. return model.findAll(options);
  351. }
  352. async count(instance, options) {
  353. const sequelize = this.target.sequelize;
  354. options = Utils.cloneDeep(options);
  355. options.attributes = [
  356. [sequelize.fn("COUNT", sequelize.col([this.target.name, this.targetKeyField].join("."))), "count"]
  357. ];
  358. options.joinTableAttributes = [];
  359. options.raw = true;
  360. options.plain = true;
  361. const result = await this.get(instance, options);
  362. return parseInt(result.count, 10);
  363. }
  364. async has(sourceInstance, instances, options) {
  365. if (!Array.isArray(instances)) {
  366. instances = [instances];
  367. }
  368. options = __spreadProps(__spreadValues({
  369. raw: true
  370. }, options), {
  371. scope: false,
  372. attributes: [this.targetKey],
  373. joinTableAttributes: []
  374. });
  375. const instancePrimaryKeys = instances.map((instance) => {
  376. if (instance instanceof this.target) {
  377. return instance.where();
  378. }
  379. return {
  380. [this.targetKey]: instance
  381. };
  382. });
  383. options.where = {
  384. [Op.and]: [
  385. { [Op.or]: instancePrimaryKeys },
  386. options.where
  387. ]
  388. };
  389. const associatedObjects = await this.get(sourceInstance, options);
  390. return _.differenceWith(instancePrimaryKeys, associatedObjects, (a, b) => _.isEqual(a[this.targetKey], b[this.targetKey])).length === 0;
  391. }
  392. async set(sourceInstance, newAssociatedObjects, options) {
  393. options = options || {};
  394. const sourceKey = this.sourceKey;
  395. const targetKey = this.targetKey;
  396. const identifier = this.identifier;
  397. const foreignIdentifier = this.foreignIdentifier;
  398. if (newAssociatedObjects === null) {
  399. newAssociatedObjects = [];
  400. } else {
  401. newAssociatedObjects = this.toInstanceArray(newAssociatedObjects);
  402. }
  403. const where = __spreadValues({
  404. [identifier]: sourceInstance.get(sourceKey)
  405. }, this.through.scope);
  406. const updateAssociations = (currentRows) => {
  407. const obsoleteAssociations = [];
  408. const promises = [];
  409. const defaultAttributes = options.through || {};
  410. const unassociatedObjects = newAssociatedObjects.filter((obj) => !currentRows.some((currentRow) => currentRow[foreignIdentifier] === obj.get(targetKey)));
  411. for (const currentRow of currentRows) {
  412. const newObj = newAssociatedObjects.find((obj) => currentRow[foreignIdentifier] === obj.get(targetKey));
  413. if (!newObj) {
  414. obsoleteAssociations.push(currentRow);
  415. } else {
  416. let throughAttributes = newObj[this.through.model.name];
  417. if (throughAttributes instanceof this.through.model) {
  418. throughAttributes = {};
  419. }
  420. const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
  421. if (Object.keys(attributes).length) {
  422. promises.push(this.through.model.update(attributes, Object.assign(options, {
  423. where: {
  424. [identifier]: sourceInstance.get(sourceKey),
  425. [foreignIdentifier]: newObj.get(targetKey)
  426. }
  427. })));
  428. }
  429. }
  430. }
  431. if (obsoleteAssociations.length > 0) {
  432. promises.push(this.through.model.destroy(__spreadProps(__spreadValues({}, options), {
  433. where: __spreadValues({
  434. [identifier]: sourceInstance.get(sourceKey),
  435. [foreignIdentifier]: obsoleteAssociations.map((obsoleteAssociation) => obsoleteAssociation[foreignIdentifier])
  436. }, this.through.scope)
  437. })));
  438. }
  439. if (unassociatedObjects.length > 0) {
  440. const bulk = unassociatedObjects.map((unassociatedObject) => {
  441. return __spreadValues(__spreadProps(__spreadValues(__spreadValues({}, defaultAttributes), unassociatedObject[this.through.model.name]), {
  442. [identifier]: sourceInstance.get(sourceKey),
  443. [foreignIdentifier]: unassociatedObject.get(targetKey)
  444. }), this.through.scope);
  445. });
  446. promises.push(this.through.model.bulkCreate(bulk, __spreadValues({ validate: true }, options)));
  447. }
  448. return Promise.all(promises);
  449. };
  450. try {
  451. const currentRows = await this.through.model.findAll(__spreadProps(__spreadValues({}, options), { where, raw: true }));
  452. return await updateAssociations(currentRows);
  453. } catch (error) {
  454. if (error instanceof EmptyResultError)
  455. return updateAssociations([]);
  456. throw error;
  457. }
  458. }
  459. async add(sourceInstance, newInstances, options) {
  460. if (!newInstances)
  461. return Promise.resolve();
  462. options = __spreadValues({}, options);
  463. const association = this;
  464. const sourceKey = association.sourceKey;
  465. const targetKey = association.targetKey;
  466. const identifier = association.identifier;
  467. const foreignIdentifier = association.foreignIdentifier;
  468. const defaultAttributes = options.through || {};
  469. newInstances = association.toInstanceArray(newInstances);
  470. const where = __spreadValues({
  471. [identifier]: sourceInstance.get(sourceKey),
  472. [foreignIdentifier]: newInstances.map((newInstance) => newInstance.get(targetKey))
  473. }, association.through.scope);
  474. const updateAssociations = (currentRows) => {
  475. const promises = [];
  476. const unassociatedObjects = [];
  477. const changedAssociations = [];
  478. for (const obj of newInstances) {
  479. const existingAssociation = currentRows && currentRows.find((current) => current[foreignIdentifier] === obj.get(targetKey));
  480. if (!existingAssociation) {
  481. unassociatedObjects.push(obj);
  482. } else {
  483. const throughAttributes = obj[association.through.model.name];
  484. const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
  485. if (Object.keys(attributes).some((attribute) => attributes[attribute] !== existingAssociation[attribute])) {
  486. changedAssociations.push(obj);
  487. }
  488. }
  489. }
  490. if (unassociatedObjects.length > 0) {
  491. const bulk = unassociatedObjects.map((unassociatedObject) => {
  492. const throughAttributes = unassociatedObject[association.through.model.name];
  493. const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
  494. attributes[identifier] = sourceInstance.get(sourceKey);
  495. attributes[foreignIdentifier] = unassociatedObject.get(targetKey);
  496. Object.assign(attributes, association.through.scope);
  497. return attributes;
  498. });
  499. promises.push(association.through.model.bulkCreate(bulk, __spreadValues({ validate: true }, options)));
  500. }
  501. for (const assoc of changedAssociations) {
  502. let throughAttributes = assoc[association.through.model.name];
  503. const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
  504. if (throughAttributes instanceof association.through.model) {
  505. throughAttributes = {};
  506. }
  507. promises.push(association.through.model.update(attributes, Object.assign(options, { where: {
  508. [identifier]: sourceInstance.get(sourceKey),
  509. [foreignIdentifier]: assoc.get(targetKey)
  510. } })));
  511. }
  512. return Promise.all(promises);
  513. };
  514. try {
  515. const currentRows = await association.through.model.findAll(__spreadProps(__spreadValues({}, options), { where, raw: true }));
  516. const [associations] = await updateAssociations(currentRows);
  517. return associations;
  518. } catch (error) {
  519. if (error instanceof EmptyResultError)
  520. return updateAssociations();
  521. throw error;
  522. }
  523. }
  524. remove(sourceInstance, oldAssociatedObjects, options) {
  525. const association = this;
  526. options = options || {};
  527. oldAssociatedObjects = association.toInstanceArray(oldAssociatedObjects);
  528. const where = {
  529. [association.identifier]: sourceInstance.get(association.sourceKey),
  530. [association.foreignIdentifier]: oldAssociatedObjects.map((newInstance) => newInstance.get(association.targetKey))
  531. };
  532. return association.through.model.destroy(__spreadProps(__spreadValues({}, options), { where }));
  533. }
  534. async create(sourceInstance, values, options) {
  535. const association = this;
  536. options = options || {};
  537. values = values || {};
  538. if (Array.isArray(options)) {
  539. options = {
  540. fields: options
  541. };
  542. }
  543. if (association.scope) {
  544. Object.assign(values, association.scope);
  545. if (options.fields) {
  546. options.fields = options.fields.concat(Object.keys(association.scope));
  547. }
  548. }
  549. const newAssociatedObject = await association.target.create(values, options);
  550. await sourceInstance[association.accessors.add](newAssociatedObject, _.omit(options, ["fields"]));
  551. return newAssociatedObject;
  552. }
  553. verifyAssociationAlias(alias) {
  554. if (typeof alias === "string") {
  555. return this.as === alias;
  556. }
  557. if (alias && alias.plural) {
  558. return this.as === alias.plural;
  559. }
  560. return !this.isAliased;
  561. }
  562. }
  563. module.exports = BelongsToMany;
  564. module.exports.BelongsToMany = BelongsToMany;
  565. module.exports.default = BelongsToMany;
  566. //# sourceMappingURL=belongs-to-many.js.map