Skip to content
This repository has been archived by the owner on Apr 22, 2024. It is now read-only.

Creating Models

Connor Krupp edited this page May 17, 2017 · 1 revision

MongoDB & Mongoose

We use Mongoose to interface with MongoDB, our database for MHacks. MongoDB is a NoSQL database great for its flexibility, performance, and ease of use. Combined with Mongoose, it is surprisingly easy to create schemas and query models.

Let's use a simplified version of our User schema as an example.

Declaring a Schema

var schema = new mongoose.Schema({
    full_name: String,
    email: {
        type: String,
        required: true,
        index: {
            unique: true
        }
    },
    email_verified: Boolean,
    password: {
        type: String,
        required: true
    },
    created_at: {
        type: Date,
        default: Date.now
    }
});

In the code above, we create a schema with 5 attributes of various types. You can see how we can declare the type, and optionally add qualifiers like whether the attribute is required, a default value for that attribute, as well as indices (for faster queries at the expense of extra disk space).

Adding Methods

We can also add methods to the schema, allowing us to easily use our models for more than just encapsulation of data.

schema.methods.checkPassword = function (supppliedPassword) {
    return bcrypt.compare(suppliedPassword, this.password);
}

This method checks the suppliedPassword with the password of the instance this function is called on: userInstance.checkPassword('hunter2'). The bcrypt compare function is asynchronous, so this method actually returns a Promise. So, the call site for this method will look like this:

userInstance.checkPassword('hunter2').then((res) => {
    // Passwords do match
}).catch((err) => {
    // Password didn't match
});

Adding Middleware

Sometimes, it is necessary for middleware to run when using a model. For example, what if a password is updated? We can use middleware to ensure that the password is appropriately salted and hashed before saving.

var passwordMiddleware = function(next) {
    var user = this;

    if (!user.isModified('password')) {
        return next();
    }

    bcrypt.hash(user.password, 10).then((hash) => {
        user.password = hash;
        return next();
    }).catch((err) => {
        console.error(err);
        return next(err);
    });
};

schema.pre('save', passwordMiddleware);
schema.pre('update', passwordMiddleware);

This declares this middleware to run before saving and before updating an instance of this schema

Exporting the Model

Before this model can be used by anyone, we must initialize and export the model

var model = mongoose.model('User', schema);

module.exports = model;

This initializes the model with the name 'User' to have this schema we have defined. It then exports it so it is available to anyone who imports this file.