public async Task <IActionResult> UpdateRecipe([FromRoute] int id, [FromBody] CreateUpdateRecipeDto receivedRecipe, CancellationToken cancellation)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }

                var recipe = await db.Recipes
                             .Include(r => r.Ingredients)
                             .ThenInclude(i => i.Ingredient)
                             .FirstAsync(r => r.Id == id, cancellation);

                if (recipe == null)
                {
                    return(NotFound());
                }

                cancellation.ThrowIfCancellationRequested();

                mapper.Map(receivedRecipe, recipe);

                var ingredientNames = receivedRecipe.Ingredients.Select(i => i.Name).ToArray();

                cancellation.ThrowIfCancellationRequested();

                await db.Ingredients.Where(i => ingredientNames.Contains(i.Name))
                .AsNoTracking()
                .ForEachAsync(i =>
                {
                    // Set the id of each mapped ingredient to the one from the db
                    var map          = recipe.Ingredients.First(_ => _.Ingredient.Name == i.Name);
                    map.IngredientId = i.Id;
                }, cancellation);

                await db.SaveChangesAsync(cancellation);

                return(NoContent());
            }
            catch (OperationCanceledException)
            {
                logger.LogInformation($"{nameof(RecipeController)}::{nameof(UpdateRecipe)} got cancelled");
                throw;
            }
        }
        public async Task <IActionResult> AddRecipe([FromBody] CreateUpdateRecipeDto receivedRecipe, CancellationToken cancellation)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }

                if (await db.Recipes.AnyAsync(r => r.Name == receivedRecipe.Name, cancellation))
                {
                    return(BadRequest("already exists"));
                }

                cancellation.ThrowIfCancellationRequested();

                var recipe = mapper.Map <Recipe>(receivedRecipe);

                recipe.DateCreated = DateTime.Now;

                db.Recipes.Add(recipe);

                var ingredientNames = receivedRecipe.Ingredients.Select(i => i.Name).ToArray();

                cancellation.ThrowIfCancellationRequested();

                await db.Ingredients.Where(i => ingredientNames.Contains(i.Name))
                .AsNoTracking()
                .ForEachAsync(i =>
                {
                    // Set the id of each mapped ingredient to the one from the db
                    recipe.Ingredients.Select(map => map.Ingredient).First(_ => _.Name == i.Name).Id = i.Id;
                }, cancellation);

                await db.SaveChangesAsync(cancellation);

                cancellation.ThrowIfCancellationRequested();

                return(CreatedAtAction(nameof(GetById), new { id = recipe.Id }, mapper.Map <RecipeDto>(recipe)));
            }
            catch (OperationCanceledException)
            {
                logger.LogInformation($"{nameof(RecipeController)}::{nameof(AddRecipe)} got cancelled");
                throw;
            }
        }