From 9ab712cfd8fe2fdeed4b1a7a888640714e619e0f Mon Sep 17 00:00:00 2001
From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com>
Date: Thu, 30 Nov 2023 16:02:43 -0500
Subject: [PATCH 1/5] Update populate.md
---
docs/populate.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 2 deletions(-)
diff --git a/docs/populate.md b/docs/populate.md
index 7cb145bc64..fedf6ec27c 100644
--- a/docs/populate.md
+++ b/docs/populate.md
@@ -46,7 +46,8 @@ the `Story` model.
Populating multiple existing documents
Populating across multiple levels
Populating across Databases
- Dynamic References via refPath
+ Dynamic References via refPath
+ Dynamic References via ref
Populate Virtuals
Populate Virtuals: The Count Option
Populate Virtuals: The Match Option
@@ -469,7 +470,7 @@ const events = await Event.
populate({ path: 'conversation', model: Conversation });
```
-
+
Mongoose can also populate from multiple collections based on the value
of a property in the document. Let's say you're building a schema for
@@ -553,6 +554,47 @@ comments[0].product.name; // "The Count of Monte Cristo"
comments[1].blogPost.title; // "Top 10 French Novels"
```
+You could also assign a function to `refPath`, making it so that it
+selects a refpath depending on a value on the document being populated. For example.
+
+```javascript
+const commentSchema = new Schema({
+ body: { type: String, required: true },
+ doc: {
+ type: Schema.Types.ObjectId,
+ required: true,
+ refPath: () => {
+ return this.docModel; // 'this' refers to the document being populated
+ }
+ },
+ docModel: {
+ type: String,
+ required: true,
+ enum: ['BlogPost', 'Product']
+ }
+});
+
+const Product = mongoose.model('Product', new Schema({ name: String }));
+const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
+const Comment = mongoose.model('Comment', commentSchema);
+
+const book = await Product.create({ name: 'The Count of Monte Cristo' });
+const post = await BlogPost.create({ title: 'Top 10 French Novels' });
+
+const commentOnBook = await Comment.create({
+ body: 'Great read',
+ doc: book._id,
+ docModel: 'Product'
+});
+
+const commentOnPost = await Comment.create({
+ body: 'Very informative',
+ doc: post._id,
+ docModel: 'BlogPost'
+});
+
+```
+
Defining separate `blogPost` and `product` properties works for this simple
example. But, if you decide to allow users to also comment on articles or
other comments, you'll need to add more properties to your schema. You'll
@@ -561,6 +603,28 @@ also need an extra `populate()` call for every property, unless you use
Using `refPath` means you only need 2 schema paths and one `populate()` call
regardless of how many models your `commentSchema` can point to.
+
+
+Just like `refPath`, `ref` can also be assigned a function
+
+```javascript
+const commentSchema = new Schema({
+ body: { type: String, required: true },
+ verifiedBuyer: Boolean
+ doc: {
+ type: Schema.Types.ObjectId,
+ required: true,
+ ref: () => {
+ return this.verifiedBuyer ? 'Product' : 'BlogPost'; // 'this' refers to the document being populated
+ }
+ },
+});
+
+const Product = mongoose.model('Product', new Schema({ name: String }));
+const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
+const Comment = mongoose.model('Comment', commentSchema);
+```
+
So far you've only populated based on the `_id` field.
From b7d46a0fa20c019474079969fd77b8485dc093a4 Mon Sep 17 00:00:00 2001
From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com>
Date: Thu, 30 Nov 2023 16:42:41 -0500
Subject: [PATCH 2/5] change from arrow function to function declaration
---
docs/populate.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/populate.md b/docs/populate.md
index fedf6ec27c..9e815a9e10 100644
--- a/docs/populate.md
+++ b/docs/populate.md
@@ -563,7 +563,7 @@ const commentSchema = new Schema({
doc: {
type: Schema.Types.ObjectId,
required: true,
- refPath: () => {
+ refPath: function () {
return this.docModel; // 'this' refers to the document being populated
}
},
@@ -605,7 +605,7 @@ regardless of how many models your `commentSchema` can point to.
-Just like `refPath`, `ref` can also be assigned a function
+Just like `refPath`, `ref` can also be assigned a function.
```javascript
const commentSchema = new Schema({
@@ -614,7 +614,7 @@ const commentSchema = new Schema({
doc: {
type: Schema.Types.ObjectId,
required: true,
- ref: () => {
+ ref: function() {
return this.verifiedBuyer ? 'Product' : 'BlogPost'; // 'this' refers to the document being populated
}
},
From b60452fd3bc445a3d2cb88865dea9dd7facf7934 Mon Sep 17 00:00:00 2001
From: Daniel Diaz <39510674+IslandRhythms@users.noreply.github.com>
Date: Thu, 30 Nov 2023 16:48:44 -0500
Subject: [PATCH 3/5] Update populate.md
---
docs/populate.md | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/docs/populate.md b/docs/populate.md
index 9e815a9e10..e1c6aac400 100644
--- a/docs/populate.md
+++ b/docs/populate.md
@@ -560,22 +560,30 @@ selects a refpath depending on a value on the document being populated. For exam
```javascript
const commentSchema = new Schema({
body: { type: String, required: true },
+ verifiedBuyer: Boolean,
doc: {
type: Schema.Types.ObjectId,
required: true,
refPath: function () {
- return this.docModel; // 'this' refers to the document being populated
+ return this.verifiedBuyer ? this.otherOption : this.docModel; // 'this' refers to the document being populated
}
},
docModel: {
type: String,
required: true,
- enum: ['BlogPost', 'Product']
+ enum: ['BlogPost', 'Review']
+ },
+ otherOption: {
+ type: String,
+ required: true,
+ enum: ['Vendor', 'Product']
}
});
const Product = mongoose.model('Product', new Schema({ name: String }));
const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
+const Vendor = mongoose.model('Vendor', new Schema({ productType: String }));
+const Review = mongoose.model('Review', new Schema({ rating: String }));
const Comment = mongoose.model('Comment', commentSchema);
const book = await Product.create({ name: 'The Count of Monte Cristo' });
@@ -583,14 +591,18 @@ const post = await BlogPost.create({ title: 'Top 10 French Novels' });
const commentOnBook = await Comment.create({
body: 'Great read',
+ verifiedBuyer: true
doc: book._id,
- docModel: 'Product'
+ docModel: 'Review',
+ otherOption: 'Product'
});
const commentOnPost = await Comment.create({
body: 'Very informative',
+ verifiedBuyer: false,
doc: post._id,
- docModel: 'BlogPost'
+ docModel: 'BlogPost',
+ otherOption: 'Vendor'
});
```
From 12bdc2347afd478de2db9234ad4083dedb925dc6 Mon Sep 17 00:00:00 2001
From: Valeri Karpov
Date: Thu, 30 Nov 2023 17:06:54 -0500
Subject: [PATCH 4/5] Update populate.md
---
docs/populate.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/populate.md b/docs/populate.md
index e1c6aac400..358caad0d8 100644
--- a/docs/populate.md
+++ b/docs/populate.md
@@ -47,7 +47,7 @@ the `Story` model.
Populating across multiple levels
Populating across Databases
Dynamic References via refPath
- Dynamic References via ref
+ Dynamic References via ref
Populate Virtuals
Populate Virtuals: The Count Option
Populate Virtuals: The Match Option
From ce4487cb090ca0c3b48a594222afe6a4529475cd Mon Sep 17 00:00:00 2001
From: Valeri Karpov
Date: Thu, 30 Nov 2023 17:11:28 -0500
Subject: [PATCH 5/5] Update populate.md
---
docs/populate.md | 62 +++++++++++++-----------------------------------
1 file changed, 17 insertions(+), 45 deletions(-)
diff --git a/docs/populate.md b/docs/populate.md
index 358caad0d8..9bc16f6596 100644
--- a/docs/populate.md
+++ b/docs/populate.md
@@ -554,67 +554,43 @@ comments[0].product.name; // "The Count of Monte Cristo"
comments[1].blogPost.title; // "Top 10 French Novels"
```
-You could also assign a function to `refPath`, making it so that it
-selects a refpath depending on a value on the document being populated. For example.
+Defining separate `blogPost` and `product` properties works for this simple
+example. But, if you decide to allow users to also comment on articles or
+other comments, you'll need to add more properties to your schema. You'll
+also need an extra `populate()` call for every property, unless you use
+[mongoose-autopopulate](https://www.npmjs.com/package/mongoose-autopopulate).
+Using `refPath` means you only need 2 schema paths and one `populate()` call
+regardless of how many models your `commentSchema` can point to.
+
+You could also assign a function to `refPath`, which means Mongoose selects a refPath depending on a value on the document being populated.
```javascript
const commentSchema = new Schema({
body: { type: String, required: true },
- verifiedBuyer: Boolean,
- doc: {
+ commentType: {
+ type: String,
+ enum: ['comment', 'review']
+ },
+ entityId: {
type: Schema.Types.ObjectId,
required: true,
refPath: function () {
- return this.verifiedBuyer ? this.otherOption : this.docModel; // 'this' refers to the document being populated
+ return this.commentType === 'review' ? this.reviewEntityModel : this.commentEntityModel; // 'this' refers to the document being populated
}
},
- docModel: {
+ commentEntityModel: {
type: String,
required: true,
enum: ['BlogPost', 'Review']
},
- otherOption: {
+ reviewEntityModel: {
type: String,
required: true,
enum: ['Vendor', 'Product']
}
});
-
-const Product = mongoose.model('Product', new Schema({ name: String }));
-const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
-const Vendor = mongoose.model('Vendor', new Schema({ productType: String }));
-const Review = mongoose.model('Review', new Schema({ rating: String }));
-const Comment = mongoose.model('Comment', commentSchema);
-
-const book = await Product.create({ name: 'The Count of Monte Cristo' });
-const post = await BlogPost.create({ title: 'Top 10 French Novels' });
-
-const commentOnBook = await Comment.create({
- body: 'Great read',
- verifiedBuyer: true
- doc: book._id,
- docModel: 'Review',
- otherOption: 'Product'
-});
-
-const commentOnPost = await Comment.create({
- body: 'Very informative',
- verifiedBuyer: false,
- doc: post._id,
- docModel: 'BlogPost',
- otherOption: 'Vendor'
-});
-
```
-Defining separate `blogPost` and `product` properties works for this simple
-example. But, if you decide to allow users to also comment on articles or
-other comments, you'll need to add more properties to your schema. You'll
-also need an extra `populate()` call for every property, unless you use
-[mongoose-autopopulate](https://www.npmjs.com/package/mongoose-autopopulate).
-Using `refPath` means you only need 2 schema paths and one `populate()` call
-regardless of how many models your `commentSchema` can point to.
-
Just like `refPath`, `ref` can also be assigned a function.
@@ -631,10 +607,6 @@ const commentSchema = new Schema({
}
},
});
-
-const Product = mongoose.model('Product', new Schema({ name: String }));
-const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
-const Comment = mongoose.model('Comment', commentSchema);
```