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

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) { ...@@ -21,6 +21,7 @@ var HasOne = function(srcModel, targetModel, options) {
this.source = srcModel; this.source = srcModel;
this.target = targetModel; this.target = targetModel;
this.options = options; this.options = options;
this.scope = options.scope;
this.isSingleAssociation = true; this.isSingleAssociation = true;
this.isSelfAssociation = (this.source === this.target); this.isSelfAssociation = (this.source === this.target);
this.as = this.options.as; this.as = this.options.as;
...@@ -134,6 +135,10 @@ HasOne.prototype.injectGetter = function(instancePrototype) { ...@@ -134,6 +135,10 @@ HasOne.prototype.injectGetter = function(instancePrototype) {
var where = {}; var where = {};
where[association.foreignKey] = this.get(association.sourceIdentifier); where[association.foreignKey] = this.get(association.sourceIdentifier);
if (association.scope) {
_.assign(where, association.scope);
}
options = association.target.__optClone(options) || {}; options = association.target.__optClone(options) || {};
options.where = { options.where = {
...@@ -190,7 +195,10 @@ HasOne.prototype.injectSetter = function(instancePrototype) { ...@@ -190,7 +195,10 @@ HasOne.prototype.injectSetter = function(instancePrototype) {
isNewRecord: false isNewRecord: false
}); });
} }
_.assign(associatedInstance, association.scope);
associatedInstance.set(association.foreignKey, instance.get(association.sourceIdentifier)); associatedInstance.set(association.foreignKey, instance.get(association.sourceIdentifier));
return associatedInstance.save(options); return associatedInstance.save(options);
} }
return null; return null;
...@@ -208,6 +216,13 @@ HasOne.prototype.injectCreator = function(instancePrototype) { ...@@ -208,6 +216,13 @@ HasOne.prototype.injectCreator = function(instancePrototype) {
values = values || {}; values = values || {};
options = options || {}; 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); values[association.foreignKey] = instance.get(association.sourceIdentifier);
if (options.fields) options.fields.push(association.foreignKey); if (options.fields) options.fields.push(association.foreignKey);
return association.target.create(values, options); return association.target.create(values, options);
......
...@@ -17,7 +17,11 @@ describe(Support.getTestDialectTeaser('associations'), function() { ...@@ -17,7 +17,11 @@ describe(Support.getTestDialectTeaser('associations'), function() {
this.Comment = this.sequelize.define('comment', { this.Comment = this.sequelize.define('comment', {
title: Sequelize.STRING, title: Sequelize.STRING,
commentable: Sequelize.STRING, commentable: Sequelize.STRING,
commentable_id: Sequelize.INTEGER commentable_id: Sequelize.INTEGER,
isMain: {
type: Sequelize.BOOLEAN,
defaultValue: false
}
}, { }, {
instanceMethods: { instanceMethods: {
getItem: function() { getItem: function() {
...@@ -29,12 +33,26 @@ describe(Support.getTestDialectTeaser('associations'), function() { ...@@ -29,12 +33,26 @@ describe(Support.getTestDialectTeaser('associations'), function() {
this.Post.addScope('withComments', { this.Post.addScope('withComments', {
include: [this.Comment] include: [this.Comment]
}); });
this.Post.addScope('withMainComment', {
include: [{
model: this.Comment,
as: 'mainComment'
}]
});
this.Post.hasMany(this.Comment, { this.Post.hasMany(this.Comment, {
foreignKey: 'commentable_id', foreignKey: 'commentable_id',
scope: { scope: {
commentable: 'post' commentable: 'post'
} }
}); });
this.Post.hasOne(this.Comment, {
foreignKey: 'commentable_id',
as: 'mainComment',
scope: {
commentable: 'post',
isMain: true
}
});
this.Comment.belongsTo(this.Post, { this.Comment.belongsTo(this.Post, {
foreignKey: 'commentable_id', foreignKey: 'commentable_id',
as: 'post' as: 'post'
...@@ -63,6 +81,60 @@ describe(Support.getTestDialectTeaser('associations'), function() { ...@@ -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() { describe('1:M', function() {
it('should create, find and include associations with scope values', function() { it('should create, find and include associations with scope values', function() {
var self = this; var self = this;
......
...@@ -86,7 +86,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -86,7 +86,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
where: { where: {
active: false active: false
} }
}, }
} }
}); });
...@@ -106,12 +106,12 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -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: 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.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: 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) { }).spread(function (u1, u2, u3, u4, u5, c1, c2) {
return Promise.all([ return Promise.all([
c1.setUsers([u1, u2, u3, u4]), c1.setUsers([u1, u2, u3, u4]),
c2.setUsers([u5]), c2.setUsers([u5])
]); ]);
}); });
}); });
...@@ -178,8 +178,8 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -178,8 +178,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.ScopeMe.findById(1); return this.ScopeMe.findById(1);
}).then(function (user) { }).then(function (user) {
return user.getProfile({ scope: false }); return user.getProfile({ scope: false });
}).then(function (project) { }).then(function (profile) {
expect(project).to.be.ok; expect(profile).to.be.ok;
}); });
}); });
...@@ -217,8 +217,8 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -217,8 +217,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.ScopeMe.findById(1); return this.ScopeMe.findById(1);
}).then(function (user) { }).then(function (user) {
return user.getProfile(); return user.getProfile();
}).then(function (project) { }).then(function (profile) {
expect(project).not.to.be.ok; expect(profile).not.to.be.ok;
}); });
}); });
...@@ -258,8 +258,8 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -258,8 +258,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.ScopeMe.findById(1); return this.ScopeMe.findById(1);
}).then(function (user) { }).then(function (user) {
return user.getProfile({ scope: 'notActive' }); return user.getProfile({ scope: 'notActive' });
}).then(function (project) { }).then(function (profile) {
expect(project).not.to.be.ok; 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!