diff --git a/lib/service.js b/lib/service.js index 16eef106..3a8f11ac 100755 --- a/lib/service.js +++ b/lib/service.js @@ -12,7 +12,12 @@ class Service extends AdapterService { } super(Object.assign({ - id: '_id' + id: '_id', + filters: Object.assign({ + $populate (value) { + return value; + } + }, options.filters) }, options)); this.discriminatorKey = this.Model.schema.options.discriminatorKey; @@ -43,7 +48,7 @@ class Service extends AdapterService { const { filters, query, paginate } = this.filterQuery(params); const discriminator = (params.query || {})[this.discriminatorKey] || this.discriminatorKey; const model = this.discriminators[discriminator] || this.Model; - const q = model.find(_.omit(query, '$populate')).lean(this.lean); + const q = model.find(query).lean(this.lean); // $select uses a specific find syntax, so it has to come first. if (Array.isArray(filters.$select)) { @@ -75,8 +80,8 @@ class Service extends AdapterService { } // Handle $populate - if (query.$populate) { - q.populate(query.$populate); + if (filters.$populate) { + q.populate(filters.$populate); } let executeQuery = total => q.exec().then(data => { @@ -111,11 +116,11 @@ class Service extends AdapterService { const discriminator = query[this.discriminatorKey] || this.discriminatorKey; const model = this.discriminators[discriminator] || this.Model; - let modelQuery = model.findOne(_.omit(query, '$populate')); + let modelQuery = model.findOne(query); // Handle $populate - if (query.$populate) { - modelQuery = modelQuery.populate(query.$populate); + if (filters.$populate) { + modelQuery = modelQuery.populate(filters.$populate); } // Handle $select @@ -143,14 +148,22 @@ class Service extends AdapterService { _create (_data, params = {}) { const discriminator = (params.query || {})[this.discriminatorKey] || this.discriminatorKey; const model = this.discriminators[discriminator] || this.Model; - const data = Array.isArray(_data) ? _data : [ _data ]; + const { query: { $populate } = {} } = params; + const isMulti = Array.isArray(_data); + const data = isMulti ? _data : [ _data ]; return model.create(data, params.mongoose).then(results => { + if ($populate) { + return Promise.all(results.map(result => this.Model.populate(result, $populate))); + } + + return results; + }).then(results => { if (this.lean) { results = results.map(item => (item.toObject ? item.toObject() : item)); } - return Array.isArray(_data) ? results : results[0]; + return isMulti ? results : results[0]; }).then(select(params, this.id)).catch(errorHandler); } @@ -164,7 +177,7 @@ class Service extends AdapterService { data = data.toObject(); } - const { query } = this.filterQuery(params); + const { query, filters } = this.filterQuery(params); const options = Object.assign({ new: true, overwrite: this.overwrite, @@ -186,10 +199,10 @@ class Service extends AdapterService { const discriminator = query[this.discriminatorKey] || this.discriminatorKey; const model = this.discriminators[discriminator] || this.Model; - let modelQuery = model.findOneAndUpdate(_.omit(query, '$populate'), data, options); + let modelQuery = model.findOneAndUpdate(query, data, options); - if (query.$populate) { - modelQuery = modelQuery.populate(query.$populate); + if (filters.$populate) { + modelQuery = modelQuery.populate(filters.$populate); } return modelQuery.lean(this.lean).exec() @@ -252,7 +265,7 @@ class Service extends AdapterService { paginate: false, query: Object.assign({ [this.id]: { $in: idList } - }, query) + }, params.query) }) : Object.assign({}, params, { paginate: false }); @@ -262,7 +275,7 @@ class Service extends AdapterService { const discriminator = query[this.discriminatorKey] || this.discriminatorKey; const model = this.discriminators[discriminator] || this.Model; return model - .updateMany(_.omit(query, '$populate'), data, options) + .updateMany(query, data, options) .lean(this.lean) .exec() .then(writeResult => { @@ -283,6 +296,7 @@ class Service extends AdapterService { if (params.collation) { query.collation = params.collation; } + if (id !== null) { query[this.id] = id; diff --git a/test/index.test.js b/test/index.test.js index acad3c6b..b0216445 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -408,6 +408,20 @@ describe('Feathers Mongoose Service', () => { expect(data.pets[0].name).to.equal('Rufus'); }); + it('can $populate with .create (#268)', async () => { + const params = { + query: { + $populate: ['pets'] + } + }; + + const user = await people.create({ name: 'Dougler', age: 3, pets: [ _petIds.Rufus ] }, params); + + expect(user.pets[0].name).to.equal('Rufus'); + + await people.remove(user._id); + }); + it('can $push an item onto an array with update', async () => { const margeaux = await pets.create({ type: 'cat', name: 'Margeaux' });