@@ -628,11 +628,30 @@ class CoreMongooseArray extends Array {
628
628
629
629
_checkManualPopulation ( this , arguments ) ;
630
630
631
+ const parent = this [ arrayParentSymbol ] ;
631
632
let values = [ ] . map . call ( arguments , this . _mapCast , this ) ;
632
- values = this [ arraySchemaSymbol ] . applySetters ( values , this [ arrayParentSymbol ] , undefined ,
633
+ values = this [ arraySchemaSymbol ] . applySetters ( values , parent , undefined ,
633
634
undefined , { skipDocumentArrayCast : true } ) ;
634
635
const ret = [ ] . push . apply ( this , values ) ;
635
636
637
+ // If this is a document array, each element may contain single
638
+ // populated paths, so we need to modify the top-level document's
639
+ // populated cache. See gh-8247.
640
+ if ( this . isMongooseDocumentArray && parent . $__ . populated != null ) {
641
+ const populatedPaths = Object . keys ( parent . $__ . populated ) .
642
+ filter ( p => p . startsWith ( this [ arrayPathSymbol ] + '.' ) ) ;
643
+
644
+ for ( const path of populatedPaths ) {
645
+ const remnant = path . slice ( ( this [ arrayPathSymbol ] + '.' ) . length ) ;
646
+ if ( ! Array . isArray ( parent . $__ . populated [ path ] . value ) ) {
647
+ continue ;
648
+ }
649
+ for ( const val of values ) {
650
+ parent . $__ . populated [ path ] . value . push ( val . populated ( remnant ) ) ;
651
+ }
652
+ }
653
+ }
654
+
636
655
this . _registerAtomic ( '$push' , values ) ;
637
656
this . _markModified ( ) ;
638
657
return ret ;
0 commit comments