From bf460f3e0baf4d334939f77cfc5d6168755bc1f7 Mon Sep 17 00:00:00 2001 From: Kyle Zarazan Date: Wed, 27 Nov 2024 16:25:40 -0700 Subject: [PATCH] add meal plans --- Gemfile | 1 + Gemfile.lock | 2 + app/controllers/meal_plans_controller.rb | 44 +++++++++++++++++++ app/controllers/recipes_controller.rb | 19 ++++++-- .../components/recipes/RecipeEdit.tsx | 2 + .../components/recipes/RecipeForm.tsx | 10 +++++ .../components/recipes/RecipeNew.tsx | 2 + app/javascript/types/types.ts | 1 + app/models/meal_plan.rb | 3 ++ app/models/recipe.rb | 1 + config/routes.rb | 6 +++ db/migrate/20241126205103_create_meal_plan.rb | 8 ++++ ...0241126205410_create_meal_plans_recipes.rb | 9 ++++ db/schema.rb | 15 ++++++- 14 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 app/controllers/meal_plans_controller.rb create mode 100644 app/models/meal_plan.rb create mode 100644 db/migrate/20241126205103_create_meal_plan.rb create mode 100644 db/migrate/20241126205410_create_meal_plans_recipes.rb diff --git a/Gemfile b/Gemfile index c543341..d6ef62b 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ gem "cssbundling-rails" gem "jbuilder" gem "faker" gem "humanize" +gem "ruby-measurement" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] # gem "bcrypt", "~> 3.1.7" diff --git a/Gemfile.lock b/Gemfile.lock index 2231b23..73d4cad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -274,6 +274,7 @@ GEM rubocop-minitest rubocop-performance rubocop-rails + ruby-measurement (1.3.0) ruby-progressbar (1.13.0) rubyzip (2.3.2) securerandom (0.3.1) @@ -355,6 +356,7 @@ DEPENDENCIES puma (>= 5.0) rails (~> 8.0.0) rubocop-rails-omakase + ruby-measurement selenium-webdriver solid_cable solid_cache diff --git a/app/controllers/meal_plans_controller.rb b/app/controllers/meal_plans_controller.rb new file mode 100644 index 0000000..754374f --- /dev/null +++ b/app/controllers/meal_plans_controller.rb @@ -0,0 +1,44 @@ +class MealPlansController < ApplicationController + + def create + @meal_plan = MealPlan.new(meal_plan_params) + + if @meal_plan.save + render json: @meal_plan, status: :created + else + render json: @meal_plan.errors, status: :unprocessable_entity + end + end + + def show + @meal_plan = MealPlan.find(params[:id]) + end + + def add_recipe + @meal_plan = MealPlan.find(params[:id]) + @recipe = Recipe.find(params[:recipe_id]) + + if @meal_plan.recipes << @recipe + render json: @meal_plan, status: :ok + else + render json: { error: "Could not add recipe to meal plan" }, status: :unprocessable_entity + end + end + + def remove_recipe + @meal_plan = MealPlan.find(params[:id]) + @recipe = Recipe.find(params[:recipe_id]) + + if @meal_plan.recipes.delete(@recipe) + render json: @meal_plan, status: :ok + else + render json: { error: "Could not remove recipe from meal plan" }, status: :unprocessable_entity + end + end + + private + + def meal_plan_params + params.require(:meal_plan).permit(:name) + end +end diff --git a/app/controllers/recipes_controller.rb b/app/controllers/recipes_controller.rb index 36e5b30..405bc3b 100644 --- a/app/controllers/recipes_controller.rb +++ b/app/controllers/recipes_controller.rb @@ -13,6 +13,10 @@ def create end end + def show + @recipe = Recipe.find(params[:id]) + end + def update @recipe = Recipe.find(params[:id]) if @recipe.update(recipe_params) @@ -34,12 +38,21 @@ def destroy private def recipe_params - rp = params.require(:recipe).permit(:name, :description, ingredients_attributes: [:id, :food_id, :food_name, :measurement, :_destroy]) + rp = params.require(:recipe).permit( + :name, + :description, + :instructions, + ingredients_attributes: [:id, :food_id, :food_name, :measurement, :_destroy] + ) + create_new_foods(rp) + end + + def create_new_foods(rp) rp[:ingredients_attributes].each do |ingredient| food_name = ingredient.delete(:food_name) if ingredient[:food_id].blank? || ingredient[:food_id] == 0 - new_food = Food.new(name: food_name) - ingredient[:food_id] = new_food.id if new_food.save + food = Food.find_or_initialize_by(name: food_name) + ingredient[:food_id] = food.id if food.persisted? || food.save end end rp diff --git a/app/javascript/components/recipes/RecipeEdit.tsx b/app/javascript/components/recipes/RecipeEdit.tsx index 2213e21..26a85a8 100644 --- a/app/javascript/components/recipes/RecipeEdit.tsx +++ b/app/javascript/components/recipes/RecipeEdit.tsx @@ -20,6 +20,7 @@ const EditRecipeForm: React.FC = () => { const [formData, setFormData] = useState({ name: '', description: '', + instructions: '', ingredients_attributes: [] }); @@ -30,6 +31,7 @@ const EditRecipeForm: React.FC = () => { setFormData({ name: recipe.name, description: recipe.description, + instructions: recipe.instructions, ingredients_attributes: recipe.ingredients }); } diff --git a/app/javascript/components/recipes/RecipeForm.tsx b/app/javascript/components/recipes/RecipeForm.tsx index 176d9f1..fd14c71 100644 --- a/app/javascript/components/recipes/RecipeForm.tsx +++ b/app/javascript/components/recipes/RecipeForm.tsx @@ -5,6 +5,7 @@ import { Ingredient } from '../../types/types'; export interface RecipeFormData { name: string; description: string; + instructions: string; ingredients_attributes: Ingredient[]; } @@ -113,6 +114,15 @@ const RecipeForm: React.FC = ({ formData, setFormData, onSubmit /> +
+ +