-
Notifications
You must be signed in to change notification settings - Fork 0
API Info Model
We need to requires some libraries in order to set the Info model for MongoDB. (using mongoose).
var mongoose = require('mongoose');
var Promise = require('bluebird');
var moment = require('moment');
var Vote = require('./Vote');
var Controller = require('../controller');
moment().format();
mongoose.Promise = require('bluebird');
Promise.promisifyAll(mongoose);
-
Mongoose used to define the schema and the model.
-
Bluebird to manipulate Promise (already built in Express but deprecated). We define bluebird as the default Promise feature with the following lines:
mongoose.Promise = require('bluebird'); Promise.promisifyAll(mongoose); -
Moment to handle date and time values.
So now, we have everything to build the info model. An information is composed of different things, we will list all the different features and explain how to represent them as a model for mongoDB.
Composition of an information:
-
Title
- Type: String, Required
-
Description
- Type: String, Required, default: ''
-
Birthdate
- Type: Date, Required, default: now()
-
Expirydate
- Type: Date, Required
-
Category
- type: String, Required, default: 'Info'
-
Location
- Type: String, Required, default: ''
-
AddInfo
- Type: String, default ''
-
UserID
- Type: String, Required
-
UserList
- Type: Object array of ID + Name, default: []
-
UserLimit
- Type: Number, Required, Min: 0, default: 0
-
AcceptOverload
- Type: Boolean, default: false
-
Votes
- Type: Array of Vote, default: []
-
VoteCount
- Type: Number, default: 0
Some of these attributes are specific for a certain category of information, like Userlist, Userlimite, AcceptOverload.
Here we defined the global schema of an information. We will handle particular cases after with methods or with the Controller class.
So to define our schema using mongoose, we have to write this:
var Schema = mongoose.Schema;
var InfoSchema = new Schema({
title : { type: String, required: true },
description : { type: String, required: true, default: '' },
birthdate : { type: Date, required: true, default: moment() },
expirydate : { type: Date, required: true },
category : { type: String, required: true, default: 'Info' },
location : { type: String, required: true, default: '' },
addInfo : { type: String, default: ''},
userID : { type: String, required: true },
userList : { type: [{ID: String, username: String}], default: []},
userLimit : { type: Number, min: 0, default: 0},
acceptOverload : { type: Boolean, default: false },
votes : { type: [Vote.schema], default: [] },
voteCount : { type: Number, default: 0}
});
As you probably noticed, we added some restrictions to our schema (required, default values, type, etc..). This is to force a good usage for the data stockage. If one of these restrictions is not respected, mongoose will emit an error and won't perform any action.
We can also define some methods for this model. For this project we defined 5 methods which are basically helpers to handle datas or to get datas rapidly and easily:
-
getRemainingTime() We get the time difference between the expiry and birthdate.
InfoSchema.methods.getRemainingTime = function() { var birthMoment = moment(this.birthdate); var deathMoment = moment(this.expirydate); var timeleft = deathMoment.diff(birthMoment); return timeleft.format('HH:mm:ss').toJSON(); }; -
isFull() This method is designed especially for events, telling us if the event is full or not (can we join it? or not?)
InfoSchema.methods.isFull = function() { if(this.acceptOverload) return false; else if(this.userList.length >= this.userLimit) return true; else return false; }; -
getCurrentSize() This method is also designed for events, returning the number of current members of the event.
InfoSchema.methods.getCurrentSize = function() { return this.userList.length; } -
updateVoteCount() Update the voteCount of the info by retrieving all the values in the votes array. We typically call this method after each new vote.
InfoSchema.methods.updateVoteCount = function() { var total = 0; var vote; for (var i = this.votes.length - 1; i >= 0; i--) { vote = this.votes[i]; total += vote.value; } this.voteCount = total; }; -
updateInfos() This method is used to update each attribute in an information (if a new value is provided).
InfoSchema.methods.updateInfos = function(data) { if(data.title && data.title != '') { this.title = Controller.sanitizeString(data.title); } if(data.description) { this.description = Controller.sanitizeString(data.description); } if(data.birthdate) { var newBirthDate = moment(data.birthdate, moment.ISO_8601); var timeFromNow = newBirthDate.diff(moment()); if( timeFromNow >= 0 && timeFromNow <= 86400000) { // this is 24h in ms this.birthdate = newBirthDate; } } if(data.expirydate) { var newExpiryDate = moment(data.expirydate); var timeFromBegin = newExpiryDate.diff(this.birthdate); if( timeFromBegin >= 0 && timeFromBegin <= 86400000) { // this is 24h in ms this.expirydate = newExpiryDate; } } if(data.category) { this.category = Controller.sanitizeString(data.category); } if(data.location) { this.location = Controller.sanitizeString(data.location); } if(data.addInfo) { this.addInfo = Controller.sanitizeString(data.addInfo); } if(data.acceptOverload != this.acceptOverload) { this.acceptOverload = data.acceptOverload; } if(data.userLimit) { this.userLimit = data.userLimit; } if(this.acceptOverload == true) { this.userLimit = ''; } }
Finally we defined the model and export it in order to use it in other files.
var Info = mongoose.model('Info', InfoSchema);
module.exports = Info;
©Quickshare 2016-2017 | [Contact](mailto:contact@quickshare.info?subject=[Contact QuickShare WIKI]) | Written with StackEdit.