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

Commit b992988b by Mick Hansen

feat(include): provide basic include.association support (as opposed to include.model/as pair)

1 parent ed091ccb
var Association = function() {
};
module.exports = Association;
\ No newline at end of file
......@@ -2,10 +2,14 @@
var Utils = require('./../utils')
, Helpers = require('./helpers')
, Transaction = require('../transaction');
, Transaction = require('../transaction')
, Association = require('./base')
, util = require('util');
module.exports = (function() {
var BelongsTo = function(source, target, options) {
Association.call(this);
this.associationType = 'BelongsTo';
this.source = source;
this.target = target;
......@@ -64,6 +68,8 @@ module.exports = (function() {
};
};
util.inherits(BelongsTo, Association);
// the id is in the source table
BelongsTo.prototype.injectAttributes = function() {
var newAttributes = {};
......
......@@ -3,6 +3,7 @@
var Utils = require('./utils')
, Instance = require('./instance')
, Attribute = require('./model/attribute')
, Association = require('./associations/base')
, DataTypes = require('./data-types')
, Util = require('util')
, sql = require('sql')
......@@ -653,6 +654,7 @@ module.exports = (function() {
* @param {Array<Object|Model>} [options.include] A list of associations to eagerly load using a left join. Supported is either `{ include: [ Model1, Model2, ...]}` or `{ include: [{ model: Model1, as: 'Alias' }]}`. If your association are set up with an `as` (eg. `X.hasMany(Y, { as: 'Z }`, you need to specify Z in the as attribute when eager loading Y).
* @param {Model} [options.include[].model] The model you want to eagerly load
* @param {String} [options.include[].as] The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` / `belongsTo`, this should be the singular name, and for `hasMany`, it should be the plural
* @param {Association} [options.include[].association] The association you want to eagerly load. (This can be used instead of providing a model/as pair)
* @param {Object} [options.include[].where] Where clauses to apply to the child models. Note that this converts the eager load to an inner join, unless you explicitly set `required: true`
* @param {Array<String>} [options.include[].attributes] A list of attributes to select from the child model
* @param {Boolean} [options.include[].required] If true, converts to an inner join, which means that the parent model will only be loaded if it has any matching children. True if `include.where` is set, false otherwise.
......@@ -1766,10 +1768,12 @@ module.exports = (function() {
// convert all included elements to { Model: Model } form
var includes = options.include = options.include.map(function(include) {
if (include instanceof Model) {
if (include instanceof Association) {
include = { association: include };
} else if (include instanceof Model) {
include = { model: include };
} else if (typeof include !== 'object') {
throw new Error('Include unexpected. Element has to be either an instance of Model or an object.');
throw new Error('Include unexpected. Element has to be either a Model, an Association or an object.');
} else if (include.hasOwnProperty('daoFactory')) {
include.model = include.daoFactory;
}
......@@ -1814,10 +1818,12 @@ module.exports = (function() {
Model.$validateIncludedElements = validateIncludedElements;
var validateIncludedElement = function(include, tableNames) {
if (!include.hasOwnProperty('model')) {
throw new Error('Include malformed. Expected attributes: model');
if (!include.hasOwnProperty('model') && !include.hasOwnProperty('association')) {
throw new Error('Include malformed. Expected attributes: model or association');
}
if (include.association) include.model = include.association.source;
tableNames[include.model.getTableName()] = true;
if (include.hasOwnProperty('attributes')) {
......@@ -1839,7 +1845,7 @@ module.exports = (function() {
}
// check if the current Model is actually associated with the passed Model - or it's a pseudo include
var association = this.getAssociation(include.model, include.as);
var association = include.association || this.getAssociation(include.model, include.as);
if (association) {
include.association = association;
include.as = association.as;
......
......@@ -2,6 +2,7 @@
/* jshint expr: true */
var chai = require('chai')
, Sequelize = require('../index')
, Promise = Sequelize.Promise
, expect = chai.expect
, Support = require(__dirname + '/support')
, DataTypes = require(__dirname + "/../lib/data-types")
......@@ -54,6 +55,31 @@ describe(Support.getTestDialectTeaser("Include"), function () {
})
})
it('should support including a belongsTo association rather than a model/as pair', function () {
var Company = this.sequelize.define('Company', {})
, Person = this.sequelize.define('Person', {});
Person.relation = {
Employer: Person.belongsTo(Company, {as: 'employer'})
};
return this.sequelize.sync({force: true}).then(function () {
return Promise.join(
Person.create(),
Company.create()
).spread(function (person, company) {
return person.setEmployer(company);
});
}).then(function () {
return Person.find({
include: [Person.relation.Employer]
}).then(function (person) {
expect(person).to.be.ok;
expect(person.employer).to.be.ok;
});
});
});
it('should support a simple nested belongsTo -> belongsTo include', function (done) {
var Task = this.sequelize.define('Task', {})
, User = this.sequelize.define('User', {})
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!