API Reference Source

lib/associations/helpers.js

  1. 'use strict';
  2.  
  3. function checkNamingCollision(association) {
  4. if (Object.prototype.hasOwnProperty.call(association.source.rawAttributes, association.as)) {
  5. throw new Error(
  6. `Naming collision between attribute '${association.as}'` +
  7. ` and association '${association.as}' on model ${association.source.name}` +
  8. '. To remedy this, change either foreignKey or as in your association definition'
  9. );
  10. }
  11. }
  12. exports.checkNamingCollision = checkNamingCollision;
  13.  
  14. function addForeignKeyConstraints(newAttribute, source, target, options, key) {
  15. // FK constraints are opt-in: users must either set `foreignKeyConstraints`
  16. // on the association, or request an `onDelete` or `onUpdate` behavior
  17.  
  18. if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {
  19. // Find primary keys: composite keys not supported with this approach
  20. const primaryKeys = Object.keys(source.primaryKeys)
  21. .map(primaryKeyAttribute => source.rawAttributes[primaryKeyAttribute].field || primaryKeyAttribute);
  22.  
  23. if (primaryKeys.length === 1 || !primaryKeys.includes(key)) {
  24. if (source._schema) {
  25. newAttribute.references = {
  26. model: source.sequelize.getQueryInterface().QueryGenerator.addSchema({
  27. tableName: source.tableName,
  28. _schema: source._schema,
  29. _schemaDelimiter: source._schemaDelimiter
  30. })
  31. };
  32. } else {
  33. newAttribute.references = { model: source.tableName };
  34. }
  35.  
  36. newAttribute.references.key = key || primaryKeys[0];
  37. newAttribute.onDelete = options.onDelete;
  38. newAttribute.onUpdate = options.onUpdate;
  39. }
  40. }
  41. }
  42. exports.addForeignKeyConstraints = addForeignKeyConstraints;
  43.  
  44. /**
  45. * Mixin (inject) association methods to model prototype
  46. *
  47. * @private
  48. *
  49. * @param {Object} association instance
  50. * @param {Object} obj Model prototype
  51. * @param {Array} methods Method names to inject
  52. * @param {Object} aliases Mapping between model and association method names
  53. *
  54. */
  55. function mixinMethods(association, obj, methods, aliases) {
  56. aliases = aliases || {};
  57.  
  58. for (const method of methods) {
  59. // don't override custom methods
  60. if (!Object.prototype.hasOwnProperty.call(obj, association.accessors[method])) {
  61. const realMethod = aliases[method] || method;
  62.  
  63. obj[association.accessors[method]] = function() {
  64. return association[realMethod](this, ...Array.from(arguments));
  65. };
  66. }
  67. }
  68. }
  69. exports.mixinMethods = mixinMethods;