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

Commit e4b95678 by Mick Hansen

Merge pull request #5113 from Verdier/fix-scope

Add support for scope in has-one association
2 parents d2f1af65 df205ab9
......@@ -21,6 +21,7 @@ var HasOne = function(srcModel, targetModel, options) {
this.source = srcModel;
this.target = targetModel;
this.options = options;
this.scope = options.scope;
this.isSingleAssociation = true;
this.isSelfAssociation = (this.source === this.target);
this.as = this.options.as;
......@@ -134,6 +135,10 @@ HasOne.prototype.injectGetter = function(instancePrototype) {
var where = {};
where[association.foreignKey] = this.get(association.sourceIdentifier);
if (association.scope) {
_.assign(where, association.scope);
}
options = association.target.__optClone(options) || {};
options.where = {
......@@ -190,7 +195,10 @@ HasOne.prototype.injectSetter = function(instancePrototype) {
isNewRecord: false
});
}
_.assign(associatedInstance, association.scope);
associatedInstance.set(association.foreignKey, instance.get(association.sourceIdentifier));
return associatedInstance.save(options);
}
return null;
......@@ -208,6 +216,13 @@ HasOne.prototype.injectCreator = function(instancePrototype) {
values = values || {};
options = options || {};
if (association.scope) {
Object.keys(association.scope).forEach(function (attribute) {
values[attribute] = association.scope[attribute];
if (options.fields) options.fields.push(attribute);
});
}
values[association.foreignKey] = instance.get(association.sourceIdentifier);
if (options.fields) options.fields.push(association.foreignKey);
return association.target.create(values, options);
......
......@@ -17,7 +17,11 @@ describe(Support.getTestDialectTeaser('associations'), function() {
this.Comment = this.sequelize.define('comment', {
title: Sequelize.STRING,
commentable: Sequelize.STRING,
commentable_id: Sequelize.INTEGER
commentable_id: Sequelize.INTEGER,
isMain: {
type: Sequelize.BOOLEAN,
defaultValue: false
}
}, {
instanceMethods: {
getItem: function() {
......@@ -29,12 +33,26 @@ describe(Support.getTestDialectTeaser('associations'), function() {
this.Post.addScope('withComments', {
include: [this.Comment]
});
this.Post.addScope('withMainComment', {
include: [{
model: this.Comment,
as: 'mainComment'
}]
});
this.Post.hasMany(this.Comment, {
foreignKey: 'commentable_id',
scope: {
commentable: 'post'
}
});
this.Post.hasOne(this.Comment, {
foreignKey: 'commentable_id',
as: 'mainComment',
scope: {
commentable: 'post',
isMain: true
}
});
this.Comment.belongsTo(this.Post, {
foreignKey: 'commentable_id',
as: 'post'
......@@ -63,6 +81,60 @@ describe(Support.getTestDialectTeaser('associations'), function() {
});
});
describe('1:1', function() {
it('should create, find and include associations with scope values', function() {
var self = this;
return this.sequelize.sync({force: true}).then(function() {
return Promise.join(
self.Post.create(),
self.Comment.create({
title: 'I am a comment'
}),
self.Comment.create({
title: 'I am a main comment',
isMain: true
})
);
}).bind(this).spread(function(post) {
this.post = post;
return post.createComment({
title: 'I am a post comment'
});
}).then(function(comment) {
expect(comment.get('commentable')).to.equal('post');
expect(comment.get('isMain')).to.be.false;
return this.Post.scope('withMainComment').findById(this.post.get('id'));
}).then(function(post) {
expect(post.mainComment).to.be.null;
return post.createMainComment({
title: 'I am a main post comment'
});
}).then(function(mainComment) {
this.mainComment = mainComment;
expect(mainComment.get('commentable')).to.equal('post');
expect(mainComment.get('isMain')).to.be.true;
return this.Post.scope('withMainComment').findById(this.post.id);
}).then(function (post) {
expect(post.mainComment.get('id')).to.equal(this.mainComment.get('id'));
return post.getMainComment();
}).then(function (mainComment, post) {
expect(mainComment.get('commentable')).to.equal('post');
expect(mainComment.get('isMain')).to.be.true;
return this.Comment.create({
title: 'I am a future main comment'
});
}).then(function (comment) {
return this.post.setMainComment(comment);
}).then( function () {
return this.post.getMainComment();
}).then(function (mainComment) {
expect(mainComment.get('commentable')).to.equal('post');
expect(mainComment.get('isMain')).to.be.true;
expect(mainComment.get('title')).to.equal('I am a future main comment');
});
});
});
describe('1:M', function() {
it('should create, find and include associations with scope values', function() {
var self = this;
......
......@@ -86,7 +86,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
where: {
active: false
}
},
}
}
});
......@@ -106,12 +106,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
this.ScopeMe.create({ id: 4, username: 'fred', email: 'fred@foobar.com', access_level: 3, other_value: 7, parent_id: 1}),
this.ScopeMe.create({ id: 5, username: 'bob', email: 'bob@foobar.com', access_level: 1, other_value: 9, parent_id: 5}),
this.Company.create({ id: 1, active: true}),
this.Company.create({ id: 2, active: false}),
this.Company.create({ id: 2, active: false})
]);
}).spread(function (u1, u2, u3, u4, u5, c1, c2) {
return Promise.all([
c1.setUsers([u1, u2, u3, u4]),
c2.setUsers([u5]),
c2.setUsers([u5])
]);
});
});
......@@ -178,8 +178,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.ScopeMe.findById(1);
}).then(function (user) {
return user.getProfile({ scope: false });
}).then(function (project) {
expect(project).to.be.ok;
}).then(function (profile) {
expect(profile).to.be.ok;
});
});
......@@ -217,8 +217,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.ScopeMe.findById(1);
}).then(function (user) {
return user.getProfile();
}).then(function (project) {
expect(project).not.to.be.ok;
}).then(function (profile) {
expect(profile).not.to.be.ok;
});
});
......@@ -258,8 +258,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.ScopeMe.findById(1);
}).then(function (user) {
return user.getProfile({ scope: 'notActive' });
}).then(function (project) {
expect(project).not.to.be.ok;
}).then(function (profile) {
expect(profile).not.to.be.ok;
});
});
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!