不要怂,就是干,撸起袖子干!

Commit 3ff27d10 by Felix Becker Committed by Jan Aagaard Meier

ES6 refactor: associations (#6050)

* Make BelongsTo association an ES6 class

* ES6 refactor of belongs-to.js

* Make BelongsToMany an ES6 class

* ES6 refactor of BelongsToMany

* Make HasMany an ES6 class

* ES6 refactor of HasMany

* Make HasOne an ES6 class

* ES6 refactor of HasOne

* ES6 refactor of association helpers

* ES6 refactor of associations/index.js

* ES6 refactor of association mixin
1 parent 5d7b26c2
'use strict';
var Utils = require('./../utils')
, Helpers = require('./helpers')
, _ = require('lodash')
, Transaction = require('../transaction')
, Association = require('./base')
, util = require('util');
const Utils = require('./../utils');
const Helpers = require('./helpers');
const _ = require('lodash');
const Transaction = require('../transaction');
const Association = require('./base');
/**
* One-to-one association
......@@ -14,8 +13,9 @@ var Utils = require('./../utils')
*
* @mixin BelongsTo
*/
var BelongsTo = function(source, target, options) {
Association.call(this);
class BelongsTo extends Association {
constructor(source, target, options) {
super();
this.associationType = 'BelongsTo';
this.source = source;
......@@ -69,7 +69,7 @@ var BelongsTo = function(source, target, options) {
this.options.useHooks = options.useHooks;
// Get singular name, trying to uppercase the first letter, unless the model forbids it
var singular = Utils.uppercaseFirst(this.options.name.singular);
const singular = Utils.uppercaseFirst(this.options.name.singular);
this.accessors = {
/**
......@@ -104,13 +104,11 @@ var BelongsTo = function(source, target, options) {
*/
create: 'create' + singular
};
};
util.inherits(BelongsTo, Association);
}
// the id is in the source table
BelongsTo.prototype.injectAttributes = function() {
var newAttributes = {};
// the id is in the source table
injectAttributes() {
const newAttributes = {};
newAttributes[this.foreignKey] = _.defaults({}, this.foreignKeyAttribute, {
type: this.options.keyType || this.target.rawAttributes[this.targetKey].type,
......@@ -118,7 +116,7 @@ BelongsTo.prototype.injectAttributes = function() {
});
if (this.options.constraints !== false) {
var source = this.source.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
const source = this.source.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
this.options.onDelete = this.options.onDelete || (source.allowNull ? 'SET NULL' : 'NO ACTION');
this.options.onUpdate = this.options.onUpdate || 'CASCADE';
}
......@@ -133,10 +131,10 @@ BelongsTo.prototype.injectAttributes = function() {
Helpers.checkNamingCollision(this);
return this;
};
}
BelongsTo.prototype.mixin = function(obj) {
var association = this;
mixin(obj) {
const association = this;
obj[this.accessors.get] = function(options) {
return association.get(this, options);
......@@ -144,13 +142,13 @@ BelongsTo.prototype.mixin = function(obj) {
association.injectSetter(obj);
association.injectCreator(obj);
};
}
BelongsTo.prototype.get = function(instances, options) {
var association = this
, Target = association.target
, instance
, where = {};
get(instances, options) {
const association = this;
const where = {};
let Target = association.target;
let instance;
options = Utils.cloneDeep(options);
......@@ -173,9 +171,7 @@ BelongsTo.prototype.get = function(instances, options) {
if (instances) {
where[association.targetKey] = {
$in: instances.map(function (instance) {
return instance.get(association.foreignKey);
})
$in: instances.map(instance => instance.get(association.foreignKey))
};
} else {
if (association.targetKeyIsPrimary && !options.where) {
......@@ -191,30 +187,30 @@ BelongsTo.prototype.get = function(instances, options) {
where;
if (instances) {
return Target.findAll(options).then(function (results) {
var result = {};
instances.forEach(function (instance) {
return Target.findAll(options).then(results => {
const result = {};
for (const instance of instances) {
result[instance.get(association.foreignKey, {raw: true})] = null;
});
}
results.forEach(function (instance) {
for (const instance of results) {
result[instance.get(association.targetKey, {raw: true})] = instance;
});
}
return result;
});
}
return Target.findOne(options);
};
}
// Add setAssociaton method to the prototype of the model instance
BelongsTo.prototype.injectSetter = function(instancePrototype) {
var association = this;
// Add setAssociaton method to the prototype of the model instance
injectSetter(instancePrototype) {
const association = this;
instancePrototype[this.accessors.set] = function(associatedInstance, options) {
options = options || {};
var value = associatedInstance;
let value = associatedInstance;
if (associatedInstance instanceof association.target) {
value = associatedInstance[association.targetKey];
}
......@@ -235,27 +231,29 @@ BelongsTo.prototype.injectSetter = function(instancePrototype) {
};
return this;
};
}
// Add createAssociation method to the prototype of the model instance
BelongsTo.prototype.injectCreator = function(instancePrototype) {
var association = this;
// Add createAssociation method to the prototype of the model instance
injectCreator(instancePrototype) {
const association = this;
instancePrototype[this.accessors.create] = function(values, fieldsOrOptions) {
var instance = this
, options = {};
const options = {};
if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
options.transaction = fieldsOrOptions.transaction;
}
options.logging = (fieldsOrOptions || {}).logging;
return association.target.create(values, fieldsOrOptions).then(function(newAssociatedObject) {
return instance[association.accessors.set](newAssociatedObject, options);
});
return association.target.create(values, fieldsOrOptions).then(newAssociatedObject =>
this[association.accessors.set](newAssociatedObject, options)
);
};
return this;
};
}
}
module.exports = BelongsTo;
module.exports.BelongsTo = BelongsTo;
module.exports.default = BelongsTo;
'use strict';
var Utils = require('./../utils')
, Helpers = require('./helpers')
, _ = require('lodash')
, Association = require('./base')
, util = require('util');
const Utils = require('./../utils');
const Helpers = require('./helpers');
const _ = require('lodash');
const Association = require('./base');
/**
* One-to-one association
......@@ -14,8 +13,9 @@ var Utils = require('./../utils')
*
* @mixin HasOne
*/
var HasOne = function(srcModel, targetModel, options) {
Association.call(this);
class HasOne extends Association {
constructor(srcModel, targetModel, options) {
super();
this.associationType = 'HasOne';
this.source = srcModel;
......@@ -66,7 +66,7 @@ var HasOne = function(srcModel, targetModel, options) {
}
// Get singular name, trying to uppercase the first letter, unless the model forbids it
var singular = Utils.uppercaseFirst(this.options.name.singular);
const singular = Utils.uppercaseFirst(this.options.name.singular);
this.accessors = {
/**
......@@ -100,14 +100,12 @@ var HasOne = function(srcModel, targetModel, options) {
*/
create: 'create' + singular
};
};
util.inherits(HasOne, Association);
}
// the id is in the target table
HasOne.prototype.injectAttributes = function() {
var newAttributes = {}
, keyType = this.source.rawAttributes[this.source.primaryKeyAttribute].type;
// the id is in the target table
injectAttributes() {
const newAttributes = {};
const keyType = this.source.rawAttributes[this.source.primaryKeyAttribute].type;
newAttributes[this.foreignKey] = _.defaults({}, this.foreignKeyAttribute, {
type: this.options.keyType || keyType,
......@@ -118,7 +116,7 @@ HasOne.prototype.injectAttributes = function() {
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
if (this.options.constraints !== false) {
var target = this.target.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
const target = this.target.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
this.options.onDelete = this.options.onDelete || (target.allowNull ? 'SET NULL' : 'CASCADE');
this.options.onUpdate = this.options.onUpdate || 'CASCADE';
}
......@@ -131,10 +129,10 @@ HasOne.prototype.injectAttributes = function() {
Helpers.checkNamingCollision(this);
return this;
};
}
HasOne.prototype.mixin = function(obj) {
var association = this;
mixin(obj) {
const association = this;
obj[this.accessors.get] = function(options) {
return association.get(this, options);
......@@ -142,13 +140,13 @@ HasOne.prototype.mixin = function(obj) {
association.injectSetter(obj);
association.injectCreator(obj);
};
}
HasOne.prototype.get = function(instances, options) {
var association = this
, Target = association.target
, instance
, where = {};
get(instances, options) {
const association = this;
const where = {};
let Target = association.target;
let instance;
options = Utils.cloneDeep(options);
......@@ -171,9 +169,7 @@ HasOne.prototype.get = function(instances, options) {
if (instances) {
where[association.foreignKey] = {
$in: instances.map(function (instance) {
return instance.get(association.sourceKey);
})
$in: instances.map(instance => instance.get(association.sourceKey))
};
} else {
where[association.foreignKey] = instance.get(association.sourceKey);
......@@ -188,37 +184,36 @@ HasOne.prototype.get = function(instances, options) {
where;
if (instances) {
return Target.findAll(options).then(function (results) {
var result = {};
instances.forEach(function (instance) {
return Target.findAll(options).then(results => {
const result = {};
for (const instance of instances) {
result[instance.get(association.sourceKey, {raw: true})] = null;
});
}
results.forEach(function (instance) {
for (const instance of results) {
result[instance.get(association.foreignKey, {raw: true})] = instance;
});
}
return result;
});
}
return Target.findOne(options);
};
}
HasOne.prototype.injectSetter = function(instancePrototype) {
var association = this;
injectSetter(instancePrototype) {
const association = this;
instancePrototype[this.accessors.set] = function(associatedInstance, options) {
var instance = this,
alreadyAssociated;
let alreadyAssociated;
options = _.assign({}, options, {
scope: false
});
return instance[association.accessors.get](options).then(function(oldInstance) {
return this[association.accessors.get](options).then(oldInstance => {
// TODO Use equals method once #5605 is resolved
alreadyAssociated = oldInstance && associatedInstance && _.every(association.target.primaryKeyAttributes, function(attribute) {
return oldInstance.get(attribute, {raw: true}) === associatedInstance.get(attribute, {raw: true});
});
alreadyAssociated = oldInstance && associatedInstance && _.every(association.target.primaryKeyAttributes, attribute =>
oldInstance.get(attribute, {raw: true}) === associatedInstance.get(attribute, {raw: true})
);
if (oldInstance && !alreadyAssociated) {
oldInstance[association.foreignKey] = null;
......@@ -228,10 +223,10 @@ HasOne.prototype.injectSetter = function(instancePrototype) {
association: true
}));
}
}).then(function() {
}).then(() => {
if (associatedInstance && !alreadyAssociated) {
if (!(associatedInstance instanceof association.target)) {
var tmpInstance = {};
const tmpInstance = {};
tmpInstance[association.target.primaryKeyAttribute] = associatedInstance;
associatedInstance = association.target.build(tmpInstance, {
isNewRecord: false
......@@ -239,7 +234,7 @@ HasOne.prototype.injectSetter = function(instancePrototype) {
}
_.assign(associatedInstance, association.scope);
associatedInstance.set(association.foreignKey, instance.get(association.sourceIdentifier));
associatedInstance.set(association.foreignKey, this.get(association.sourceIdentifier));
return associatedInstance.save(options);
}
......@@ -248,29 +243,29 @@ HasOne.prototype.injectSetter = function(instancePrototype) {
};
return this;
};
}
HasOne.prototype.injectCreator = function(instancePrototype) {
var association = this;
injectCreator(instancePrototype) {
const association = this;
instancePrototype[this.accessors.create] = function(values, options) {
var instance = this;
values = values || {};
options = options || {};
if (association.scope) {
Object.keys(association.scope).forEach(function (attribute) {
for (const attribute of Object.keys(association.scope)) {
values[attribute] = association.scope[attribute];
if (options.fields) options.fields.push(attribute);
});
}
}
values[association.foreignKey] = instance.get(association.sourceIdentifier);
values[association.foreignKey] = this.get(association.sourceIdentifier);
if (options.fields) options.fields.push(association.foreignKey);
return association.target.create(values, options);
};
return this;
};
}
}
module.exports = HasOne;
'use strict';
var Utils = require('./../utils');
const Utils = require('./../utils');
function checkNamingCollision (association) {
if (association.source.rawAttributes.hasOwnProperty(association.as)) {
......@@ -11,6 +11,7 @@ function checkNamingCollision (association) {
);
}
}
exports.checkNamingCollision = checkNamingCollision;
function addForeignKeyConstraints (newAttribute, source, target, options, key) {
// FK constraints are opt-in: users must either set `foreignKeyConstraints`
......@@ -19,9 +20,9 @@ function addForeignKeyConstraints (newAttribute, source, target, options, key) {
if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {
// Find primary keys: composite keys not supported with this approach
var primaryKeys = Utils._.chain(source.rawAttributes).keys()
.filter(function($key) { return source.rawAttributes[$key].primaryKey; })
.map(function($key) { return source.rawAttributes[$key].field || $key; }).value();
const primaryKeys = Utils._.chain(source.rawAttributes).keys()
.filter($key => source.rawAttributes[$key].primaryKey)
.map($key => source.rawAttributes[$key].field || $key).value();
if (primaryKeys.length === 1) {
if (!!source.$schema) {
......@@ -42,8 +43,4 @@ function addForeignKeyConstraints (newAttribute, source, target, options, key) {
}
}
}
module.exports = {
checkNamingCollision: checkNamingCollision,
addForeignKeyConstraints: addForeignKeyConstraints
};
exports.addForeignKeyConstraints = addForeignKeyConstraints;
'use strict';
var Association = require('./base');
const Association = require('./base');
Association.BelongsTo = require('./belongs-to');
Association.HasOne = require('./has-one');
Association.HasMany = require('./has-many');
Association.BelongsToMany = require('./belongs-to-many');
module.exports = Association;
module.exports.default = Association;
module.exports.Association = Association;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!