@@ -46,7 +46,8 @@ the `Story` model.
46
46
<li ><a href =" #populate_multiple_documents " >Populating multiple existing documents</a ></li >
47
47
<li ><a href =" #deep-populate " >Populating across multiple levels</a ></li >
48
48
<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>
50
51
<li ><a href =" #populate-virtuals " >Populate Virtuals</a ></li >
51
52
<li ><a href =" #count " >Populate Virtuals: The Count Option</a ></li >
52
53
<li ><a href =" #match " >Populate Virtuals: The Match Option</a ></li >
@@ -469,7 +470,7 @@ const events = await Event.
469
470
populate ({ path: ' conversation' , model: Conversation });
470
471
```
471
472
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 >
473
474
474
475
Mongoose can also populate from multiple collections based on the value
475
476
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"
553
554
comments[1 ].blogPost .title ; // "Top 10 French Novels"
554
555
```
555
556
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
+
556
598
Defining separate ` blogPost ` and ` product ` properties works for this simple
557
599
example. But, if you decide to allow users to also comment on articles or
558
600
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
561
603
Using ` refPath ` means you only need 2 schema paths and one ` populate() ` call
562
604
regardless of how many models your ` commentSchema ` can point to.
563
605
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
+
564
628
<h2 id =" populate-virtuals " ><a href =" #populate-virtuals " >Populate Virtuals</a ></h2 >
565
629
566
630
So far you've only populated based on the ` _id ` field.
0 commit comments