import { Document, model, Schema, DocumentQuery, Types } from 'mongoose'; import { accessibleRecordsPlugin } from '@casl/mongoose'; import { User } from '../user'; import { IngredientList, IngredientListSchema } from '../ingredient'; import { ManualRecipeCollection } from '../collection'; export interface RecipeYield { quanity: number; item: string; } export interface RecipeAttribution { text: string; link: string; } export interface RecipeProps { title: string; ownerId: Types.ObjectId; ingredientList: IngredientList; instructions: string; tags: string[]; // yeild?: IYeild; // attribution?: Schema.Types.ObjectId | string; } export type Recipe = RecipeProps & Document & { getOwner: () => DocumentQuery; }; // Mongoose Setup export const recipeSchema = new Schema({ title: { type: String }, ownerId: { type: Schema.Types.ObjectId, required: true }, ingredientList: { type: IngredientListSchema, default: { nodes: [] } }, instructions: { type: String, default: '' }, tags: [{ type: String }], }); // Custom Methods recipeSchema.methods = { /** * Get the owner of the recipe */ getOwner() { return this.model('User').findById(this.ownerId); }, }; // Hooks recipeSchema.pre('remove', async function(next) { // remove recipe from all collections const collections = await ManualRecipeCollection.find({ 'nodes.recipe': this._id, }); collections.forEach(async collection => { collection.removeRecipe(this._id); await collection.save(); }); }); recipeSchema.post('findOneAndDelete', async result => { // remove recipe from all collections const collections = await ManualRecipeCollection.find({ 'nodes.recipe': result._id, }); collections.forEach(async collection => { collection.removeRecipe(result._id); await collection.save(); }); }); // Plugins recipeSchema.plugin(accessibleRecordsPlugin); export const Recipe = model('Recipe', recipeSchema);