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

Commit 209069e1 by Jan Aagaard Meier

Pleasing code climate, abstracting duplicated code

1 parent 82b29168
...@@ -65,9 +65,7 @@ module.exports = (function() { ...@@ -65,9 +65,7 @@ module.exports = (function() {
// Sync attributes and setters/getters to DAO prototype // Sync attributes and setters/getters to DAO prototype
this.source.refreshAttributes(); this.source.refreshAttributes();
if (this.source.rawAttributes.hasOwnProperty(this.as)) { Helpers.checkNamingCollision(this);
throw new Error("Naming collision between attribute '" + this.as + "' and association '" + this.as + "' on model " + this.source.name + '. To remedy this, change either foreignKey or as in your association definition');
}
return this; return this;
}; };
......
...@@ -261,9 +261,7 @@ module.exports = (function() { ...@@ -261,9 +261,7 @@ module.exports = (function() {
this.target.refreshAttributes(); this.target.refreshAttributes();
this.source.refreshAttributes(); this.source.refreshAttributes();
if (this.source.rawAttributes.hasOwnProperty(this.as)) { Helpers.checkNamingCollision(this);
throw new Error("Naming collision between attribute '" + this.as + "' and association '" + this.as + "' on model " + this.source.name + '. To remedy this, change either foreignKey or as in your association definition');
}
return this; return this;
}; };
......
...@@ -67,9 +67,7 @@ module.exports = (function() { ...@@ -67,9 +67,7 @@ module.exports = (function() {
// Sync attributes and setters/getters to DAO prototype // Sync attributes and setters/getters to DAO prototype
this.target.refreshAttributes(); this.target.refreshAttributes();
if (this.source.rawAttributes.hasOwnProperty(this.as)) { Helpers.checkNamingCollision(this);
throw new Error("Naming collision between attribute '" + this.as + "' and association '" + this.as + "' on model " + this.source.name + '. To remedy this, change either foreignKey or as in your association definition');
}
return this; return this;
}; };
......
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
var Utils = require('./../utils'); var Utils = require('./../utils');
module.exports = { module.exports = {
checkNamingCollision: function (assocition) {
if (assocition.source.rawAttributes.hasOwnProperty(assocition.as)) {
throw new Error("Naming collision between attribute '" + assocition.as + "' and association '" + assocition.as + "' on model " + assocition.source.name + '. To remedy this, change either foreignKey or as in your association definition');
}
},
addForeignKeyConstraints: function(newAttribute, source, target, options) { addForeignKeyConstraints: function(newAttribute, source, target, options) {
// FK constraints are opt-in: users must either set `foreignKeyConstraints` // FK constraints are opt-in: users must either set `foreignKeyConstraints`
......
...@@ -93,6 +93,31 @@ var Utils = require('./../utils') ...@@ -93,6 +93,31 @@ var Utils = require('./../utils')
*/ */
var Mixin = module.exports = function() {}; var Mixin = module.exports = function() {};
// The logic for hasOne and belongsTo is exactly the same
var singleLinked = function (Type) {
return function(targetModel, options) {
if (!(targetModel instanceof this.sequelize.Model)) {
throw new Error(this.name + "." + Utils._.lowercaseFirst(Type.toString()) + " called with something that's not an instance of Sequelize.Model");
}
var sourceModel = this;
// Since this is a mixin, we'll need a unique variable name for hooks (since Model will override our hooks option)
options = options || {};
options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
// the id is in the foreign table
var association = new Type(sourceModel, targetModel, Utils._.extend(options, sourceModel.options));
sourceModel.associations[association.associationAccessor] = association.injectAttributes();
association.injectGetter(sourceModel.Instance.prototype);
association.injectSetter(sourceModel.Instance.prototype);
association.injectCreator(sourceModel.Instance.prototype);
return association;
};
};
/** /**
* Creates an association between this (the source) and the provided target. The foreign key is added on the target. * Creates an association between this (the source) and the provided target. The foreign key is added on the target.
* *
...@@ -115,28 +140,7 @@ var Mixin = module.exports = function() {}; ...@@ -115,28 +140,7 @@ var Mixin = module.exports = function() {};
* @param {string} [options.onUpdate='CASCADE'] * @param {string} [options.onUpdate='CASCADE']
* @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key. * @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key.
*/ */
Mixin.hasOne = function(targetModel, options) { Mixin.hasOne = singleLinked(HasOne);
if (!(targetModel instanceof this.sequelize.Model)) {
throw new Error(this.name + ".hasOne called with something that's not an instance of Sequelize.Model");
}
var sourceModel = this;
// Since this is a mixin, we'll need a unique variable name for hooks (since Model will override our hooks option)
options = options || {};
options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
// the id is in the foreign table
var association = new HasOne(sourceModel, targetModel, Utils._.extend(options, sourceModel.options));
sourceModel.associations[association.associationAccessor] = association.injectAttributes();
association.injectGetter(sourceModel.Instance.prototype);
association.injectSetter(sourceModel.Instance.prototype);
association.injectCreator(sourceModel.Instance.prototype);
return association;
};
/** /**
* Creates an association between this (the source) and the provided target. The foreign key is added on the source. * Creates an association between this (the source) and the provided target. The foreign key is added on the source.
...@@ -160,28 +164,7 @@ Mixin.hasOne = function(targetModel, options) { ...@@ -160,28 +164,7 @@ Mixin.hasOne = function(targetModel, options) {
* @param {string} [options.onUpdate='CASCADE'] * @param {string} [options.onUpdate='CASCADE']
* @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key. * @param {boolean} [options.constraints=true] Should on update and on delete constraints be enabled on the foreign key.
*/ */
Mixin.belongsTo = function(targetModel, options) { Mixin.belongsTo = singleLinked(BelongsTo);
if (!(targetModel instanceof this.sequelize.Model)) {
throw new Error(this.name + ".belongsTo called with something that's not an instance of Sequelize.Model");
}
var sourceModel = this;
// Since this is a mixin, we'll need a unique variable name for hooks (since Model will override our hooks option)
options = options || {};
options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
// the id is in this table
var association = new BelongsTo(sourceModel, targetModel, Utils._.extend(options, sourceModel.options));
sourceModel.associations[association.associationAccessor] = association.injectAttributes();
association.injectGetter(sourceModel.Instance.prototype);
association.injectSetter(sourceModel.Instance.prototype);
association.injectCreator(sourceModel.Instance.prototype);
return association;
};
/** /**
* Create an association that is either 1:m or n:m. * Create an association that is either 1:m or n:m.
......
...@@ -198,7 +198,7 @@ module.exports = (function() { ...@@ -198,7 +198,7 @@ module.exports = (function() {
}, },
deleteQuery: function(tableName, where, options) { deleteQuery: function(tableName, where, options) {
options = options ||  {}; options = options || {};
var table = this.quoteTable(tableName); var table = this.quoteTable(tableName);
if (options.truncate === true) { if (options.truncate === true) {
......
...@@ -206,7 +206,7 @@ module.exports = (function() { ...@@ -206,7 +206,7 @@ module.exports = (function() {
}, },
deleteQuery: function(tableName, where, options) { deleteQuery: function(tableName, where, options) {
options = options || {}; options = options || {};
var query = "DELETE FROM <%= table %> WHERE <%= where %>"; var query = "DELETE FROM <%= table %> WHERE <%= where %>";
var replacements = { var replacements = {
......
...@@ -152,7 +152,7 @@ SequelizePromise.prototype.proxy = function(promise, options) { ...@@ -152,7 +152,7 @@ SequelizePromise.prototype.proxy = function(promise, options) {
options = Utils._.extend({ options = Utils._.extend({
events: proxyEventKeys, events: proxyEventKeys,
skipEvents: [] skipEvents: []
}, options ||  {}); }, options || {});
options.events = Utils._.difference(options.events, options.skipEvents); options.events = Utils._.difference(options.events, options.skipEvents);
......
...@@ -9,7 +9,7 @@ var Utils = require('./utils') ...@@ -9,7 +9,7 @@ var Utils = require('./utils')
* To run a query under a transaction, you should pass the transaction in the options object. * To run a query under a transaction, you should pass the transaction in the options object.
* @class Transaction * @class Transaction
*/ */
var Transaction = module.exports = function(sequelize, options) { var Transaction = module.exports = function(sequelize, options) {
this.sequelize = sequelize; this.sequelize = sequelize;
this.options = Utils._.extend({ this.options = Utils._.extend({
autocommit: true, autocommit: true,
......
...@@ -16,6 +16,9 @@ var Utils = module.exports = { ...@@ -16,6 +16,9 @@ var Utils = module.exports = {
_.mixin(_s.exports()); _.mixin(_s.exports());
_.mixin({ _.mixin({
includes: _s.include, includes: _s.include,
lowercaseFirst: function (s) {
return s[0].toLowerCase() + s.slice(1);
},
camelizeIf: function(string, condition) { camelizeIf: function(string, condition) {
var result = string; var result = string;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!