You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: MongoDB/populate-method-mongoose-referencing-other-model.md
+71-1Lines changed: 71 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -103,7 +103,7 @@ function getUserWithPosts(username) {
103
103
104
104
And like magic, we have created a unified object using 2 schemas, 2 models, and 2 collections. All of the steps are important of course, but the thing that no other site made explicitly clear was that after setting up the ground work, you have to make sure you are pushing \_ids into the field you will need populated later.
105
105
106
-
### Another implementation
106
+
### 2nd Implementation
107
107
108
108
Let’s pretend we’re building a social app, and we have two models: a User and a Post:
109
109
@@ -123,6 +123,76 @@ var PostSchema = {
123
123
124
124
If you run this query: `Post.find({}).populate('user').exec(callback)`, Mongoose will look at the field user in the post, see that it has a ref to the User model, and find that user by its \_id
125
125
126
+
### 3rd Implementation in my DevBook Repo
127
+
128
+
In Profile model, I have the the 'user' property as ObjectId like below,
And in my Profile routes I have the following API endpoint
149
+
150
+
```js
151
+
router.get(
152
+
'/',
153
+
passport.authenticate('jwt', { session:false }),
154
+
(req, res) => {
155
+
consterrors= {}; // just like in user route, I want to append to the errors object for any actual errors that will be generated. And returning that object for the error case
156
+
157
+
Profile.findOne({ user:req.user.id })
158
+
.populate('user', ['name', 'avatar'])
159
+
.then(profile=> {
160
+
if (!profile) {
161
+
errors.noprofile='There is not profile for this user';
162
+
returnres.status(404).json(errors);
163
+
}
164
+
res.json(profile);
165
+
})
166
+
.catch(err=>res.status(404).json(err));
167
+
}
168
+
)
169
+
```
170
+
In the above A) I am populating my user's profile using the query builder. http://mongoosejs.com/docs/populate.html#population
171
+
172
+
B) The first parameter of .populate() is the model you wish to use for population. If not specified, populate will look up the model by the name in the Schema's 'ref' field.
C) The second parameter to .populate() is the Field selection for the population query. So here, I only wanted to show the name and avatar of the current logged-in user. So, I pass, ['name', 'avatar']
176
+
177
+
D) Population is the process of automatically replacing the specified paths in the document with document(s) from other collection(s). So, when I do the below
178
+
179
+
Profile.findOne({ user: req.user.id })
180
+
.populate('user', ['name', 'avatar'])
181
+
182
+
Populated paths are no longer set to their original _id , their value is replaced with the mongoose document returned from the database by performing a separate query before returning the results.
183
+
(http://mongoosejs.com/docs/populate.html)
184
+
185
+
E) .populate() needs a query to attach itself to, so we are using Profile.findOne() to find a profile who matches the id I provide in the argument. This returns our user document. This is when .populate() takes over.
186
+
187
+
F) Flow of .populate() -> After findOne() finds the req.user.id and assigns it to the variable 'user' > .populate() is called on user, it will go to the appropriate collection (user model in this case) , search for that _ids, and return my user with 'name' and 'avatar'
188
+
189
+
G) Why I can fetch user's model data with below line from profile route.
190
+
191
+
Profile.findOne({ user: req.user.id })
192
+
.populate('user', ['name', 'avatar'])
193
+
194
+
Because - In Profile model, I have the the 'user' property as ObjectId
0 commit comments