has-one.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. var Utils = require("./../utils")
  2. , DataTypes = require('./../data-types')
  3. , Helpers = require("./helpers")
  4. , Transaction = require("../transaction")
  5. module.exports = (function() {
  6. var HasOne = function(srcDAO, targetDAO, options) {
  7. this.associationType = 'HasOne'
  8. this.source = srcDAO
  9. this.target = targetDAO
  10. this.options = options
  11. this.isSingleAssociation = true
  12. this.isSelfAssociation = (this.source.tableName == this.target.tableName)
  13. this.as = this.options.as
  14. if (this.isSelfAssociation && !this.options.foreignKey && !!this.as) {
  15. this.options.foreignKey = Utils._.underscoredIf(Utils.singularize(this.as, this.target.options.language) + "Id", this.options.underscored)
  16. }
  17. if (this.as) {
  18. this.isAliased = true
  19. } else {
  20. this.as = Utils.singularize(this.target.tableName, this.target.options.language)
  21. }
  22. this.associationAccessor = this.isSelfAssociation
  23. ? Utils.combineTableNames(this.target.tableName, this.as)
  24. : this.as
  25. this.options.useHooks = options.useHooks
  26. this.accessors = {
  27. get: Utils._.camelize('get_' + this.as),
  28. set: Utils._.camelize('set_' + this.as),
  29. create: Utils._.camelize('create_' + this.as)
  30. }
  31. }
  32. // the id is in the target table
  33. HasOne.prototype.injectAttributes = function() {
  34. var newAttributes = {}
  35. , sourceKeys = Object.keys(this.source.primaryKeys)
  36. , keyType = ((this.source.hasPrimaryKeys && sourceKeys.length === 1) ? this.source.rawAttributes[sourceKeys[0]].type : DataTypes.INTEGER)
  37. this.identifier = this.options.foreignKey || Utils._.underscoredIf(Utils.singularize(this.source.tableName, this.source.options.language) + "Id", this.options.underscored)
  38. newAttributes[this.identifier] = { type: this.options.keyType || keyType }
  39. Utils._.defaults(this.target.rawAttributes, newAttributes)
  40. Helpers.addForeignKeyConstraints(this.target.rawAttributes[this.identifier], this.source, this.target, this.options)
  41. // Sync attributes and setters/getters to DAO prototype
  42. this.target.refreshAttributes()
  43. return this
  44. }
  45. HasOne.prototype.injectGetter = function(obj) {
  46. var self = this
  47. , smart
  48. obj[this.accessors.get] = function(params) {
  49. params = Utils._.clone(params)
  50. var primaryKeys = Object.keys(this.daoFactory.primaryKeys)
  51. , primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id'
  52. , where = {}
  53. , id = this[primaryKey] || this.id
  54. where[self.identifier] = id
  55. if (!Utils._.isUndefined(params)) {
  56. if (!Utils._.isUndefined(params.attributes)) {
  57. params = Utils._.extend({where: where}, params)
  58. } else if (!params.where) {
  59. params.where = where
  60. }
  61. } else {
  62. params = {where: where}
  63. }
  64. smart = Utils.smartWhere(params.where || [], self.target.daoFactoryManager.sequelize.options.dialect)
  65. smart = Utils.compileSmartWhere.call(self.target, smart, self.target.daoFactoryManager.sequelize.options.dialect)
  66. if (smart.length > 0) {
  67. params.where = smart
  68. }
  69. var options = {}
  70. if (params.transaction) {
  71. options.transaction = params.transaction;
  72. delete params.transaction;
  73. }
  74. return self.target.find(params, options)
  75. }
  76. return this
  77. }
  78. HasOne.prototype.injectSetter = function(obj) {
  79. var self = this
  80. obj[this.accessors.set] = function(associatedObject, options) {
  81. var instance = this
  82. , instanceKeys = Object.keys(instance.daoFactory.primaryKeys)
  83. , instanceKey = instanceKeys.length === 1 ? instanceKeys[0] : 'id'
  84. return new Utils.CustomEventEmitter(function(emitter) {
  85. instance[self.accessors.get](options).success(function(oldObj) {
  86. if (oldObj) {
  87. oldObj[self.identifier] = null
  88. oldObj
  89. .save(
  90. Utils._.extend({}, options, {
  91. fields: [self.identifier],
  92. allowNull: [self.identifier],
  93. association: true
  94. })
  95. )
  96. .success(function() {
  97. if (associatedObject) {
  98. associatedObject[self.identifier] = instance[instanceKey]
  99. associatedObject
  100. .save(options)
  101. .success(function() { emitter.emit('success', associatedObject) })
  102. .error(function(err) { emitter.emit('error', err) })
  103. } else {
  104. emitter.emit('success', null)
  105. }
  106. })
  107. } else {
  108. if (associatedObject) {
  109. associatedObject[self.identifier] = instance[instanceKey]
  110. associatedObject
  111. .save(options)
  112. .success(function() { emitter.emit('success', associatedObject) })
  113. .error(function(err) { emitter.emit('error', err) })
  114. } else {
  115. emitter.emit('success', null)
  116. }
  117. }
  118. })
  119. }).run()
  120. }
  121. return this
  122. }
  123. HasOne.prototype.injectCreator = function(obj) {
  124. var self = this
  125. obj[this.accessors.create] = function(values, fieldsOrOptions) {
  126. var instance = this
  127. , options = {}
  128. if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
  129. options.transaction = fieldsOrOptions.transaction
  130. }
  131. return new Utils.CustomEventEmitter(function(emitter) {
  132. self.target
  133. .create(values, fieldsOrOptions)
  134. .proxy(emitter, { events: ['error', 'sql'] })
  135. .success(function(newAssociatedObject) {
  136. instance[self.accessors.set](newAssociatedObject, options)
  137. .proxy(emitter)
  138. })
  139. }).run()
  140. }
  141. return this
  142. };
  143. return HasOne
  144. })()