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

Island rhythms/support ref path #115

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ module.exports = function autopopulatePlugin(schema, options) {
}

const depth = options._depth != null ? options._depth : 0;

if (options.maxDepth > 0 && depth >= options.maxDepth) {
return;
}
Expand All @@ -48,11 +47,9 @@ module.exports = function autopopulatePlugin(schema, options) {
continue;
}
pathsToPopulate[i].options.options = pathsToPopulate[i].options.options || {};

const newOptions = { _depth: depth + 1 };
if (options.maxDepth) newOptions.maxDepth = options.maxDepth;
Object.assign(pathsToPopulate[i].options.options, newOptions);

const optionsToUse = processOption.call(this,
pathsToPopulate[i].autopopulate, pathsToPopulate[i].options);
if (optionsToUse) {
Expand All @@ -65,7 +62,6 @@ module.exports = function autopopulatePlugin(schema, options) {
}
}
}

return finalPaths;
};

Expand Down Expand Up @@ -178,7 +174,6 @@ function getPathsToPopulate(schema) {
});
}
}, null, schemaStack);

return pathsToPopulate;
}

Expand Down
238 changes: 238 additions & 0 deletions test/bugs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
await db.close();
});

afterEach(function() {
db.deleteModel(/.+/);
});

beforeEach(function() {
const promises = [];
for (const modelName of Object.keys(db.models)) {
Expand Down Expand Up @@ -360,4 +364,238 @@
section = await Section.findById(section);
assert.equal(section.subdoc.subSection.name, 'foo');
});
it('supports the `refPath` option (gh-96)', async function() {
const AddressSchema = new Schema(
{
name: {
type: String
},
status: {
type: String,
enum: ['active', 'inactive'],
default: 'active'
}
},
{
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);

AddressSchema.virtual('residentials', {
ref: 'Citizen',
localField: '_id',
foreignField: 'permanentAddress.address',
justOne: false,
autopopulate: true,
match: {
status: 'active'
},
options: {
select:
'name nId'
}
});

AddressSchema.plugin(autopopulate);


const CitizenSchema = new Schema(
{
nId: {
type: String,
required: [true, 'Please add national ID card']
},
name: {
type: String,
required: [true, 'Please add a name'],
trim: true
},
permanentAddress: {
name: {
type: String,
trim: true
},
address: {
type: mongoose.Schema.ObjectId,
ref: 'Address'
}
},
father: {
type: mongoose.Schema.ObjectId,
refPath: 'fatherType',
autopopulate: true
},
fatherType: {
type: String,
enum: ['Citizen', 'Guest'],
required: true
},
status: {
type: String,
enum: ['active', 'inactive'],
default: 'active'
}
},
{
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);

CitizenSchema.plugin(autopopulate);


const Address = db.model('Address', AddressSchema);

const Citizen = db.model('Citizen', CitizenSchema);
await Address.deleteMany({});
await Citizen.deleteMany({});
const entry = await Address.create({
name: 'Another name for The Address',
status: 'active'
});

const doc = await Citizen.create({
nId: 'Hello',
name: 'There',
permanentAddress: {
name: 'The Address',
address: entry._id
},
fatherType: 'Guest'
});
await Citizen.create({
nId: 'Yo',
name: 'Test',
permanentAddress: {
name: 'The Address',
address: entry._id
},
father: doc._id,
fatherType: 'Citizen',
status: 'active'
});
const citizen = await Citizen.find();
const testDoc = citizen.find(x => x.father != null);
assert.equal(testDoc.father.fatherType, 'Guest');
});
it('`refPath` works without autopopulate on the virtual (gh-96)', async function() {
const AddressSchema = new Schema(
{
name: {
type: String
},
status: {
type: String,
enum: ['active', 'inactive'],
default: 'active'
}
},
{
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);

AddressSchema.virtual('residentials', {
ref: 'Citizen',
localField: '_id',
foreignField: 'permanentAddress.address',
justOne: false,
autopopulate: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So issue 1: you didn't remove autopopulate here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, my bad I thought it was to only be removed on the property on the schema definition, not virtual definition

match: {
status: 'active'
},
options: {
select:
'name nId'
}
});

AddressSchema.plugin(autopopulate);


const CitizenSchema = new Schema(
{
nId: {
type: String,
required: [true, 'Please add national ID card']
},
name: {
type: String,
required: [true, 'Please add a name'],
trim: true
},
permanentAddress: {
name: {
type: String,
trim: true
},
address: {
type: mongoose.Schema.ObjectId,
ref: 'Address'
}
},
father: {
type: mongoose.Schema.ObjectId,
refPath: 'fatherType'
},
fatherType: {
type: String,
enum: ['Citizen', 'Guest'],
required: true
},
status: {
type: String,
enum: ['active', 'inactive'],
default: 'active'
}
},
{
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);

CitizenSchema.plugin(autopopulate);


const Address = db.model('Address', AddressSchema);

const Citizen = db.model('Citizen', CitizenSchema);
await Address.deleteMany({});
await Citizen.deleteMany({});
const entry = await Address.create({
name: 'Another name for The Address',
status: 'active'
});

const doc = await Citizen.create({
nId: 'Hello',
name: 'There',
permanentAddress: {
name: 'The Address',
address: entry._id
},
fatherType: 'Guest'
});
await Citizen.create({
nId: 'Yo',
name: 'Test',
permanentAddress: {
name: 'The Address',
address: entry._id
},
father: doc._id,
fatherType: 'Citizen',
status: 'active'
});
const addr = await Address.findOne().populate({ path: 'residentials', populate: { path: 'permanentAddress', populate: 'address'} });

Check failure on line 598 in test/bugs.test.js

View workflow job for this annotation

GitHub Actions / Linter

A space is required before '}'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue 2: why are you populating permanentAddress when that isn't a ref? This should be path: 'permanentAddress.address'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://mongoosejs.com/docs/populate.html#deep-populate I was trying to follow the docs example for how to populate in that case. I thought that was the syntax to populate the desired field.

assert.notEqual(addr.residentials[0].permanentAddress.address.name, undefined);
});
});
Loading