Search code examples
mongoosemongoose-schema

Referencing another schema's property in Mongoose?


Consider the following:

I have a User Schema:

const UserSchema = new mongoose.Schema(
  {
    email: {
      type: String,
      required: true,
      trim: true,
      lowercase: true,
      index: { unique: true },
      validate: {
        validator: emailValidator.validate,
        message: props => `${props.value} is not a valid email address!`
      }
    },
    password: {
      type: String,
      required: true,
      trim: true,
      index: { unique: true },
      minlength: 7,
      maxlength: 11
    },
    roles: [{ type: 'String' }],
    isVerified: { type: Boolean, default: false },
    passwordResetToken: String,
    resetPasswordExpires: Date
  },
  {
    timestamps: true
  }
);


export default mongoose.models.User || mongoose.model('User', UserSchema)

And I have a Profile Schema:

const ProfileSchema = new Schema({
  name: {
    type: String,
  },
  email: {
    type: Schema.Types.ObjectId, ref: 'User',
  },
  password: {
    type: Schema.Types.ObjectId, ref: 'User',
  },
  interestedActivities: {
    type: String,
  },
  memerSince: { type: Date, default: Date.now }
})


export default mongoose.models.Profile || mongoose.model('Profile', ProfileSchema)

Does the above automagically populate the ProfileSchema with the email and and Password from User?

So in my route/api e.g. /api/profile for example will it implicitly know the two are linked?

like if I did:

import Profile from ../../models/Profile

handler
  .use(auth)
  .get((req, res) => {
     Profile.findOne(
    {
      email: req.body.email
    },
  });


export default handler

It should return the email created in User?

Thanks in advance!


Solution

  • No, it won't automatically populate e-mail and password. Also you can not assign an email to an reference place. If you try that you will get a Validation Error. Because you have just defined as ObjectId;

      email: {
        type: Schema.Types.ObjectId, ref: 'User',
      }
    

    A ref returns an userId and you can populate using this userId. Like this:

    handler
      .use(auth)
      .get((req, res) => {
         Profile.findOne(
        {
          userId: req.body.userId
        },
      }).populate('userId').select('email password bla bla');
    
    
    export default handler