title: Accessing POST variables in Mongoose model
body: <p>Using a MEAN stack (MongoDB, ExpressJS, AngularJS, and NodeJS) with Mongoose, I'm setting up a simple registration form that will include email address and password fields, among others. I'm including a password confirmation field to ensure users know what they've typed before completing registration. Pretty typical.</p>
  
  <p>However, I can't figure out how to access posted form variables in the model if they're not included in the schema. I don't want to write the password confirmation field's data to the DB, just use it for validation. I have no doubt it's a trivial issue, but everything I've found by searching has used fields included in the schema, which I've got a handle on.</p>
  
  <p>I'm assuming I need to write a schema method, and maybe a virtual, but how do I get to the value of the confirmPassword field? If someone brighter than yours truly would point me in the right direction, I'd be much obliged. Here's what I have so far (note: I omitted other controller methods, dependency declarations, etc. for brevity):</p>
  
  <p><strong>signup.jade (form)</strong></p>
  
  <pre><code>  form.signup(action="/users", method="post")
  
      .control-group
        label.control-label(for='email') Email
        .controls
          input#email(type='text', name="email", placeholder='Email', value=user.email)
  
      .control-group
        label.control-label(for='password') Password
        .controls
          input#password(type='password', name="password", placeholder='Password')
  
      .control-group
        label.control-label(for='confirmPassword') Confirm Password
        .controls
          input#password(type='password', name="confirmPassword", placeholder='Confirm Password')
  
      //- Birthdate
      include ../shared/birthdate
  
      .form-actions
        button.btn.btn-primary(type='submit') Sign Up
        &amp;nbsp;
        | or&amp;nbsp;
        a.show-login(href="/login") Log In
  </code></pre>
  
  <p><strong>users.js (controller)</strong></p>
  
  <pre><code>/**
   * Create user
   */
  exports.create = function(req, res) {
    var user = new User(req.body);
  
    user.provider = 'local';
    user.save(function(err) {
      if (err) {
        return res.render('users/signup', {
          errors: err.errors,
          user: user
        });
      }
      req.logIn(user, function(err) {
        if (err) return next(err);
        return res.redirect('/');
      });
    });
  };
  </code></pre>
  
  <p><strong>user.js (model)</strong></p>
  
  <pre><code>/**
   * Module dependencies.
   */
  var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    crypto = require('crypto'),
    _ = require('underscore');
  
  /**
   * User Schema
   */
  var UserSchema = new Schema({
    email: String,
    hashed_password: String,
    salt: String
  });
  
  /**
   * Virtuals
   */
  UserSchema.virtual('password').set(function(password) {
    this._password = password;
    this.salt = this.makeSalt();
    this.hashed_password = this.encryptPassword(password);
  }).get(function() {
    return this._password;
  });
  
  /**
   * Validations
   */
  var validatePresenceOf = function(value) {
    return value &amp;&amp; value.length;
  };
  
  // the below validations only apply if you are signing up traditionally (e.g. not fb, etc)
  UserSchema.path('email').validate(function(email) {
    return email.length;
  }, 'Email cannot be blank');
  
  UserSchema.path('hashed_password').validate(function(hashed_password) {
    return hashed_password.length;
  }, 'Password cannot be blank');
  
  
  /**
   * Pre-save hook
   */
  UserSchema.pre('save', function(next) {
    if (!this.isNew) return next();
  
    if (!validatePresenceOf(this.password))
      next(new Error('Invalid password'));
    else
      next();
  });
  
  /**
   * Methods
   */
  UserSchema.methods = {
    /**
     * Authenticate - check if the passwords are the same
     *
     * @param {String} plainText
     * @return {Boolean}
     * @api public
     */
    authenticate: function(plainText) {
      return this.encryptPassword(plainText) === this.hashed_password;
    },
  
    /**
     * Make salt
     *
     * @return {String}
     * @api public
     */
    makeSalt: function() {
      return Math.round((new Date().valueOf() * Math.random())) + '';
    },
  
    /**
     * Encrypt password
     *
     * @param {String} password
     * @return {String}
     * @api public
     */
    encryptPassword: function(password) {
      if (!password) return '';
      return crypto.createHmac('sha1', this.salt).update(password).digest('hex');
    }
  };
  
  mongoose.model('User', UserSchema);
  </code></pre>