diff --git a/Gemfile b/Gemfile index c004f4ca..840a55ab 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,7 @@ source "https://rubygems.org" gem "sinatra-activerecord" -gem "sqlite3" +gem "sqlite3", "~> 1.4.0" gem "pry" gem "require_all" +gem "rest-client" diff --git a/Gemfile.lock b/Gemfile.lock index 9589226d..0d650116 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,47 +1,63 @@ GEM remote: https://rubygems.org/ specs: - activemodel (6.0.3.1) - activesupport (= 6.0.3.1) - activerecord (6.0.3.1) - activemodel (= 6.0.3.1) - activesupport (= 6.0.3.1) - activesupport (6.0.3.1) + activemodel (6.1.1) + activesupport (= 6.1.1) + activerecord (6.1.1) + activemodel (= 6.1.1) + activesupport (= 6.1.1) + activesupport (6.1.1) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) - coderay (1.1.1) - concurrent-ruby (1.1.6) - i18n (1.8.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + coderay (1.1.3) + concurrent-ruby (1.1.8) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + http-accept (1.7.0) + http-cookie (1.0.3) + domain_name (~> 0.5) + i18n (1.8.7) concurrent-ruby (~> 1.0) - method_source (0.8.2) - minitest (5.14.1) - mustermann (1.0.3) - pry (0.10.4) - coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) + method_source (1.0.0) + mime-types (3.3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2020.1104) + minitest (5.14.3) + mustermann (1.1.1) + ruby2_keywords (~> 0.0.1) + netrc (0.11.0) + pry (0.13.1) + coderay (~> 1.1) + method_source (~> 1.0) rack (2.2.3) - rack-protection (2.0.7) + rack-protection (2.1.0) rack - require_all (1.3.3) - sinatra (2.0.7) + require_all (3.0.0) + rest-client (2.1.0) + http-accept (>= 1.7.0, < 2.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) + ruby2_keywords (0.0.4) + sinatra (2.1.0) mustermann (~> 1.0) - rack (~> 2.0) - rack-protection (= 2.0.7) + rack (~> 2.2) + rack-protection (= 2.1.0) tilt (~> 2.0) - sinatra-activerecord (2.0.12) - activerecord (>= 3.2) + sinatra-activerecord (2.0.22) + activerecord (>= 4.1) sinatra (>= 1.0) - slop (3.6.0) - sqlite3 (1.3.13) - thread_safe (0.3.6) + sqlite3 (1.4.2) tilt (2.0.10) - tzinfo (1.2.7) - thread_safe (~> 0.1) - zeitwerk (2.3.0) + tzinfo (2.0.4) + concurrent-ruby (~> 1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.7) + zeitwerk (2.4.2) PLATFORMS ruby @@ -49,8 +65,9 @@ PLATFORMS DEPENDENCIES pry require_all + rest-client sinatra-activerecord - sqlite3 + sqlite3 (~> 1.4.0) BUNDLED WITH - 1.14.6 + 2.2.3 diff --git a/app/models/ingredient.rb b/app/models/ingredient.rb new file mode 100644 index 00000000..0e969809 --- /dev/null +++ b/app/models/ingredient.rb @@ -0,0 +1,13 @@ +class Ingredient < ActiveRecord::Base + has_many :ingredient_recipes + has_many :recipes, through: :ingredient_recipes + + def self.add__or_create_ingredient(ingredient) + if Ingredient.all.find{|i| i.name == ingredient} + else + Ingredient.create(name: ingredient) + end + Ingredient.all.find{|i| i.name == ingredient} + end + +end diff --git a/app/models/ingredient_recipe.rb b/app/models/ingredient_recipe.rb new file mode 100644 index 00000000..d2547ce8 --- /dev/null +++ b/app/models/ingredient_recipe.rb @@ -0,0 +1,43 @@ +class IngredientRecipe < ActiveRecord::Base + belongs_to :ingredient + belongs_to :recipe + + def self.find_or_create_ingredient_recipe(recipe_id, ingredient_id) + if IngredientRecipe.all.find {|ir| ir.recipe_id == recipe_id && ir.ingredient_id == ingredient_id} + else + IngredientRecipe.create(recipe_id: recipe_id, ingredient_id: ingredient_id) + end + IngredientRecipe.all.find {|ir| ir.recipe_id == recipe_id && ir.ingredient_id == ingredient_id} + end + + def self.find_recipe_by_ingredient(ingredient) + + while !Ingredient.all.find {|i| i.name == ingredient} + puts "Ingredient not found. Please enter a valid ingredient" + ingredient = gets.chomp + end + + ingredient_id = Ingredient.all.find {|i| i.name == ingredient}.id + + ing_rec_instance = IngredientRecipe.all.select {|ir| ir.ingredient_id == ingredient_id} + rec_ids = ing_rec_instance.map{|i| i.recipe_id} + recs = Recipe.all.select {|r| rec_ids.any?(r.id)} + end + + def self.print_recipes(recipe) + puts "The recipes containing that ingredient are:" + recipe.each do |r| + puts r.name + end + end + + def self.random_recipe_from_ingredient(ingredient) + recipe_array = IngredientRecipe.find_recipe_by_ingredient(ingredient) + suggested_recipe = recipe_array[rand(recipe_array.size - 1)] + puts "Time to make a(n) #{suggested_recipe.name}!" + puts "Here are the ingredients:" + Recipe.list_my_ingredients(suggested_recipe) + puts suggested_recipe.instructions + suggested_recipe + end +end diff --git a/app/models/recipe.rb b/app/models/recipe.rb new file mode 100644 index 00000000..22a2ca11 --- /dev/null +++ b/app/models/recipe.rb @@ -0,0 +1,31 @@ +class Recipe < ActiveRecord::Base + has_many :ingredient_recipes + has_many :ingredients, through: :ingredient_recipes + has_many :users, through: :user_recipes + + def self.find_or_create_recipe(name, instructions) + if Recipe.all.find{|r| r.name == name} + else + Recipe.create(name: name, instructions: instructions) + end + Recipe.all.find{|r| r.name == name} + end + + def self.suggest_random_recipe(recipe_ids_already_made) + all_rec = Recipe.all + new_recipes = [] + all_rec.each do |r| + if !recipe_ids_already_made.any? {|e| e == r.id} + new_recipes.push(r) + end + end + new_recipes[rand(new_recipes.size - 1)] + end + + def self.list_my_ingredients(recipe) + recipe.ingredients.each {|i| puts i.name} + end + + +end + diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 00000000..3c2f4701 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,81 @@ +require 'pry' + +class User < ActiveRecord::Base + has_many :user_recipes + has_many :ingredients, through: :recipes + has_many :recipes, through: :user_recipes + + def self.find_or_create_by_name(name) + if User.all.find {|user| user.name == name} + else + User.create name: name + end + User.all.find {|user| user.name == name} + end + + def rate_recipe(recipe) + puts "Would you like to rate this recipe? (y/n)" + input = gets.chomp + if input == "y" + puts "How would you rate this recipe? (1-5)" + rating = gets.chomp + rating = rating.to_i + while rating < 1 || rating > 5 + puts "Rating needs to be from 1-5, please try again." + puts "How would you rate this recipe? (1-5)" + rating = gets.chomp + rating = rating.to_i + end + if UserRecipe.all.find{|i| i.user_id == self.id && i.recipe_id == recipe.id} + puts "You have already rated this recipe!" + else + UserRecipe.create(user_id: self.id, recipe_id: recipe.id, rating: rating) + end + UserRecipe.all.select{|i| i.user_id == self.id && i.recipe_id == recipe.id} + else + puts "Ok, maybe next time. " + end + end + + def show_highest_ratings + current_users_ratings = UserRecipe.all.select {|i| i.user_id == self.id} + ratings_over_4 = current_users_ratings.select {|i| i.rating >= 4} + + if ratings_over_4 + ratings_over_4.each do |i| + drink = Recipe.all.find {|recipe| recipe.id == i.recipe_id} + puts "#{drink.name}: #{i.rating} stars" + end + else + puts "You don't have any favorite recipes!" + end + end + + def list_my_recipe_ids + user_rec_array = UserRecipe.all.select {|i| i.user_id == self.id} + user_rec_array.map{|r| r.recipe_id} + end + + + def find_recipe_by_name(name) + rec_name = Recipe.all.find{|r| r.name == name} + + if !rec_name + name = get_data(name) + rec_name = Recipe.all.find{|r| r.name == name} + end + # while !rec_name + # puts "Recipe not found. Please try another." + # input_value = gets.chomp + # rec_name = Recipe.all.find{|r| r.name == input_value} + # if !rec_name + # get_data(input_value) + # end + # end + puts "Here is your #{name} recipe." + Recipe.list_my_ingredients(rec_name) + puts rec_name.instructions + self.rate_recipe(rec_name) + end + +end \ No newline at end of file diff --git a/app/models/user_recipe.rb b/app/models/user_recipe.rb new file mode 100644 index 00000000..aec244de --- /dev/null +++ b/app/models/user_recipe.rb @@ -0,0 +1,6 @@ +class UserRecipe < ActiveRecord::Base + belongs_to :user + belongs_to :recipe + + +end \ No newline at end of file diff --git a/bin/api_parsing.rb b/bin/api_parsing.rb new file mode 100644 index 00000000..8e2f5082 --- /dev/null +++ b/bin/api_parsing.rb @@ -0,0 +1,36 @@ +require_relative '../config/environment' +require 'rest-client' +require 'json' +require 'pry' + + +def get_data(name) + + + url = "https://www.thecocktaildb.com/api/json/v1/1/search.php?s=#{name}" + response = RestClient.get(url) + result = JSON.parse(response) + while result["drinks"] == nil + puts "Drink not found. Please input another recipe name." + name = gets.chomp + url = "https://www.thecocktaildb.com/api/json/v1/1/search.php?s=#{name}" + response = RestClient.get(url) + result = JSON.parse(response) + end + + drink_name = result["drinks"][0]["strDrink"] + drink_instructions = result["drinks"][0]["strInstructions"] + current_ingr_num = 1 + current_recipe = Recipe.find_or_create_recipe(drink_name, drink_instructions) + + while result["drinks"][0]["strIngredient#{current_ingr_num}"] + current_ingredient = Ingredient.add__or_create_ingredient(result["drinks"][0]["strIngredient#{current_ingr_num}"]) + IngredientRecipe.find_or_create_ingredient_recipe(current_recipe.id, current_ingredient.id) + current_ingr_num += 1 + end + + drink_name + + +end + diff --git a/bin/run.rb b/bin/run.rb old mode 100644 new mode 100755 index cf08c338..21ec6184 --- a/bin/run.rb +++ b/bin/run.rb @@ -1,5 +1,72 @@ require_relative '../config/environment' +require_relative 'api_parsing' +ActiveRecord::Base.logger = nil + +puts "Welcome to the Cocktail Recipe Interface" +puts "Please enter your username" +user_name = gets.chomp #call find_or_create_by_name method in user.rb +current_user = User.find_or_create_by_name(user_name) -puts "HELLO WORLD" +puts "Hello, #{user_name}," +sleep(1) +puts "What would you like to do?" +sleep(1) +puts "1. Find a random recipe by ingredient" + #call suggest_random_recipe using find_recipe_by_ingredient method and then + #picking a random array element in recipe.rb + #be sure to prompt_user_for_rating +puts "2. Show my favorite recipes" + #traverse through user_recipe table to find highest ratings and return as an array +puts "3. Suggest a new recipe" + #traverse through recipes and spit out random one + #be sure to prompt_user_for_rating +puts "4. Look up a recipe by recipe name" + #call find_recipe_by_name +puts "5. List all recipes with a certain ingredient" + #call find_recipe_by_ingredient method and return an array of choices +puts "6. Import a recipe from the database" +choice = gets.chomp +choice = choice.to_i +case choice + when 1 + puts "Enter the ingredient" + ingredient = gets.chomp + current_recipe = IngredientRecipe.random_recipe_from_ingredient(ingredient) + current_user.rate_recipe(current_recipe) + + when 2 + current_user.show_highest_ratings + when 3 + current_users_recipe_ids = current_user.list_my_recipe_ids + current_recipe = Recipe.suggest_random_recipe(current_users_recipe_ids) + puts "Time to make a(n) #{current_recipe.name}!" + puts "Here are the ingredients:" + Recipe.list_my_ingredients(current_recipe) + puts current_recipe.instructions + current_user.rate_recipe(current_recipe) + when 4 + puts "Enter recipe name." + name = gets.chomp + current_user.find_recipe_by_name(name) + binding.pry + when 5 + + puts "Enter the ingredient" + ingredient = gets.chomp + recipe = IngredientRecipe.find_recipe_by_ingredient(ingredient) + IngredientRecipe.print_recipes(recipe) + when 6 + + puts "Enter the recipe name you are looking for" + name = gets.chomp + get_data(name) + else + puts "That is not a valid choice." +end + + +#make method prompt_user_for_rating which will ask for a rating +#then store it with the recipe in the user_recipe table +#make method update_rating ? diff --git a/config/environment.rb b/config/environment.rb index 4dbe13e5..5eaec6f4 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -2,4 +2,6 @@ Bundler.require ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'db/development.db') -require_all 'lib' +require_all 'app' + +ActiveRecord::Base.logger = nil diff --git a/db/migrate/001_create_recipes.rb b/db/migrate/001_create_recipes.rb new file mode 100644 index 00000000..7ac876a0 --- /dev/null +++ b/db/migrate/001_create_recipes.rb @@ -0,0 +1,8 @@ +class CreateRecipes < ActiveRecord::Migration[5.1] + def change + create_table :recipes do |t| + t.string :name + t.text :instructions + end + end +end \ No newline at end of file diff --git a/db/migrate/002_create_ingredients.rb b/db/migrate/002_create_ingredients.rb new file mode 100644 index 00000000..8b71cef1 --- /dev/null +++ b/db/migrate/002_create_ingredients.rb @@ -0,0 +1,8 @@ +class CreateIngredients < ActiveRecord::Migration[5.1] + def change + create_table :ingredients do |t| + t.string :name + t.string :type + end + end +end \ No newline at end of file diff --git a/db/migrate/003_create_users.rb b/db/migrate/003_create_users.rb new file mode 100644 index 00000000..027c8b61 --- /dev/null +++ b/db/migrate/003_create_users.rb @@ -0,0 +1,7 @@ +class CreateUsers < ActiveRecord::Migration[5.1] + def change + create_table :users do |t| + t.string :name + end + end +end \ No newline at end of file diff --git a/db/migrate/004_create_ingredient_recipes.rb b/db/migrate/004_create_ingredient_recipes.rb new file mode 100644 index 00000000..c00ea099 --- /dev/null +++ b/db/migrate/004_create_ingredient_recipes.rb @@ -0,0 +1,8 @@ +class CreateIngredientRecipes < ActiveRecord::Migration[5.1] + def change + create_table :ingredient_recipes do |t| + t.integer :ingredient_id + t.integer :recipe_id + end + end +end \ No newline at end of file diff --git a/db/migrate/005_create_user_recipes.rb b/db/migrate/005_create_user_recipes.rb new file mode 100644 index 00000000..7254b9c5 --- /dev/null +++ b/db/migrate/005_create_user_recipes.rb @@ -0,0 +1,9 @@ +class CreateUserRecipes < ActiveRecord::Migration[5.1] + def change + create_table :user_recipes do |t| + t.integer :user_id + t.integer :recipe_id + t.integer :rating + end + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 00000000..edd8452b --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,40 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 5) do + + create_table "ingredient_recipes", force: :cascade do |t| + t.integer "ingredient_id" + t.integer "recipe_id" + end + + create_table "ingredients", force: :cascade do |t| + t.string "name" + t.string "type" + end + + create_table "recipes", force: :cascade do |t| + t.string "name" + t.text "instructions" + end + + create_table "user_recipes", force: :cascade do |t| + t.integer "user_id" + t.integer "recipe_id" + t.integer "rating" + end + + create_table "users", force: :cascade do |t| + t.string "name" + end + +end