Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(query): use correct Query constructor when cloning query #12418

Merged
merged 1 commit into from Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/model.js
Expand Up @@ -5069,8 +5069,9 @@ Model.compile = function compile(name, schema, collectionName, connection, base)
model.Query = function() {
Query.apply(this, arguments);
};
model.Query.prototype = Object.create(Query.prototype);
Object.setPrototypeOf(model.Query.prototype, Query.prototype);
model.Query.base = Query.base;
model.Query.prototype.constructor = Query;
applyQueryMiddleware(model.Query, model);
applyQueryMethods(model, schema.query);

Expand Down
2 changes: 1 addition & 1 deletion lib/query.js
Expand Up @@ -280,7 +280,7 @@ Query.prototype.clone = function clone() {
const model = this.model;
const collection = this.mongooseCollection;

const q = new this.constructor({}, {}, model, collection);
const q = new this.model.Query({}, {}, model, collection);

// Need to handle `sort()` separately because entries-style `sort()` syntax
// `sort([['prop1', 1]])` confuses mquery into losing the outer nested array.
Expand Down
22 changes: 18 additions & 4 deletions test/query.test.js
Expand Up @@ -3562,7 +3562,8 @@ describe('Query', function() {
let Model;

beforeEach(function() {
Model = db.model('Test', Schema({ name: String, age: Number }));
const schema = new Schema({ name: String, age: Number });
Model = db.model('Test', schema);

return Model.create([
{ name: 'Jean-Luc Picard', age: 59 },
Expand All @@ -3571,7 +3572,6 @@ describe('Query', function() {
});

it('with findOne', async function() {

const q = Model.findOne({ age: 29 });
const q2 = q.clone();

Expand All @@ -3589,7 +3589,6 @@ describe('Query', function() {
});

it('with deleteOne', async function() {

const q = Model.deleteOne({ age: 29 });

await q;
Expand All @@ -3603,7 +3602,6 @@ describe('Query', function() {
});

it('with updateOne', async function() {

const q = Model.updateOne({ name: 'Will Riker' }, { name: 'Thomas Riker' });

await q;
Expand All @@ -3628,6 +3626,22 @@ describe('Query', function() {
await q2;
assert.deepEqual(res.sort(), ['Jean-Luc Picard', 'Will Riker']);
});

it('with hooks (gh-12365)', async function() {
db.deleteModel('Test');

const schema = new Schema({ name: String, age: Number });
let called = 0;
schema.pre('find', () => ++called);
Model = db.model('Test', schema);

assert.strictEqual(called, 0);

const res = await Model.find().clone();
assert.strictEqual(called, 1);
assert.equal(res.length, 2);
assert.deepEqual(res.map(doc => doc.name).sort(), ['Jean-Luc Picard', 'Will Riker']);
});
});

it('casts filter according to discriminator schema if in filter (gh-8881)', async function() {
Expand Down