Skip to content

Commit 9ab712c

Browse files
committed
Update populate.md
1 parent 626762a commit 9ab712c

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

docs/populate.md

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ the `Story` model.
4646
<li><a href="#populate_multiple_documents">Populating multiple existing documents</a></li>
4747
<li><a href="#deep-populate">Populating across multiple levels</a></li>
4848
<li><a href="#cross-db-populate">Populating across Databases</a></li>
49-
<li><a href="#dynamic-ref">Dynamic References via <code>refPath</code></a></li>
49+
<li><a href="#dynamic-refpath">Dynamic References via <code>refPath</code></a></li>
50+
<li><a href="#dynamic-ref">Dynamic References via <code>ref</code></a></li>
5051
<li><a href="#populate-virtuals">Populate Virtuals</a></li>
5152
<li><a href="#count">Populate Virtuals: The Count Option</a></li>
5253
<li><a href="#match">Populate Virtuals: The Match Option</a></li>
@@ -469,7 +470,7 @@ const events = await Event.
469470
populate({ path: 'conversation', model: Conversation });
470471
```
471472

472-
<h2 id="dynamic-ref"><a href="#dynamic-ref">Dynamic References via <code>refPath</code></a></h2>
473+
<h2 id="dynamic-refpath"><a href="#dynamic-refpath">Dynamic References via <code>refPath</code></a></h2>
473474

474475
Mongoose can also populate from multiple collections based on the value
475476
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"
553554
comments[1].blogPost.title; // "Top 10 French Novels"
554555
```
555556

557+
You could also assign a function to `refPath`, making it so that it
558+
selects a refpath depending on a value on the document being populated. For example.
559+
560+
```javascript
561+
const commentSchema = new Schema({
562+
body: { type: String, required: true },
563+
doc: {
564+
type: Schema.Types.ObjectId,
565+
required: true,
566+
refPath: () => {
567+
return this.docModel; // 'this' refers to the document being populated
568+
}
569+
},
570+
docModel: {
571+
type: String,
572+
required: true,
573+
enum: ['BlogPost', 'Product']
574+
}
575+
});
576+
577+
const Product = mongoose.model('Product', new Schema({ name: String }));
578+
const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
579+
const Comment = mongoose.model('Comment', commentSchema);
580+
581+
const book = await Product.create({ name: 'The Count of Monte Cristo' });
582+
const post = await BlogPost.create({ title: 'Top 10 French Novels' });
583+
584+
const commentOnBook = await Comment.create({
585+
body: 'Great read',
586+
doc: book._id,
587+
docModel: 'Product'
588+
});
589+
590+
const commentOnPost = await Comment.create({
591+
body: 'Very informative',
592+
doc: post._id,
593+
docModel: 'BlogPost'
594+
});
595+
596+
```
597+
556598
Defining separate `blogPost` and `product` properties works for this simple
557599
example. But, if you decide to allow users to also comment on articles or
558600
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
561603
Using `refPath` means you only need 2 schema paths and one `populate()` call
562604
regardless of how many models your `commentSchema` can point to.
563605

606+
<h2 id="dynamic-ref"><a href="#dynamic-ref">Dynamic References via <code>ref</code></a></h2>
607+
608+
Just like `refPath`, `ref` can also be assigned a function
609+
610+
```javascript
611+
const commentSchema = new Schema({
612+
body: { type: String, required: true },
613+
verifiedBuyer: Boolean
614+
doc: {
615+
type: Schema.Types.ObjectId,
616+
required: true,
617+
ref: () => {
618+
return this.verifiedBuyer ? 'Product' : 'BlogPost'; // 'this' refers to the document being populated
619+
}
620+
},
621+
});
622+
623+
const Product = mongoose.model('Product', new Schema({ name: String }));
624+
const BlogPost = mongoose.model('BlogPost', new Schema({ title: String }));
625+
const Comment = mongoose.model('Comment', commentSchema);
626+
```
627+
564628
<h2 id="populate-virtuals"><a href="#populate-virtuals">Populate Virtuals</a></h2>
565629

566630
So far you've only populated based on the `_id` field.

0 commit comments

Comments
 (0)