Files
Jonas Schmedtmann 7f81af0ddf Initial commit 🚀
2019-06-13 15:43:15 +01:00

133 lines
3.1 KiB
JavaScript

const mongoose = require('mongoose');
const slugify = require('slugify');
// const validator = require('validator');
const tourSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, 'A tour must have a name'],
unique: true,
trim: true,
maxlength: [40, 'A tour name must have less or equal then 40 characters'],
minlength: [10, 'A tour name must have more or equal then 10 characters']
// validate: [validator.isAlpha, 'Tour name must only contain characters']
},
slug: String,
duration: {
type: Number,
required: [true, 'A tour must have a duration']
},
maxGroupSize: {
type: Number,
required: [true, 'A tour must have a group size']
},
difficulty: {
type: String,
required: [true, 'A tour must have a difficulty'],
enum: {
values: ['easy', 'medium', 'difficult'],
message: 'Difficulty is either: easy, medium, difficult'
}
},
ratingsAverage: {
type: Number,
default: 4.5,
min: [1, 'Rating must be above 1.0'],
max: [5, 'Rating must be below 5.0']
},
ratingsQuantity: {
type: Number,
default: 0
},
price: {
type: Number,
required: [true, 'A tour must have a price']
},
priceDiscount: {
type: Number,
validate: {
validator: function(val) {
// this only points to current doc on NEW document creation
return val < this.price;
},
message: 'Discount price ({VALUE}) should be below regular price'
}
},
summary: {
type: String,
trim: true,
required: [true, 'A tour must have a description']
},
description: {
type: String,
trim: true
},
imageCover: {
type: String,
required: [true, 'A tour must have a cover image']
},
images: [String],
createdAt: {
type: Date,
default: Date.now(),
select: false
},
startDates: [Date],
secretTour: {
type: Boolean,
default: false
}
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true }
}
);
tourSchema.virtual('durationWeeks').get(function() {
return this.duration / 7;
});
// DOCUMENT MIDDLEWARE: runs before .save() and .create()
tourSchema.pre('save', function(next) {
this.slug = slugify(this.name, { lower: true });
next();
});
// tourSchema.pre('save', function(next) {
// console.log('Will save document...');
// next();
// });
// tourSchema.post('save', function(doc, next) {
// console.log(doc);
// next();
// });
// QUERY MIDDLEWARE
// tourSchema.pre('find', function(next) {
tourSchema.pre(/^find/, function(next) {
this.find({ secretTour: { $ne: true } });
this.start = Date.now();
next();
});
tourSchema.post(/^find/, function(docs, next) {
console.log(`Query took ${Date.now() - this.start} milliseconds!`);
next();
});
// AGGREGATION MIDDLEWARE
tourSchema.pre('aggregate', function(next) {
this.pipeline().unshift({ $match: { secretTour: { $ne: true } } });
console.log(this.pipeline());
next();
});
const Tour = mongoose.model('Tour', tourSchema);
module.exports = Tour;