diff --git a/app/models/recipe.rb b/app/models/recipe.rb index 143ff4c..81f1ae2 100644 --- a/app/models/recipe.rb +++ b/app/models/recipe.rb @@ -10,7 +10,6 @@ class Recipe < ActiveRecord::Base accepts_nested_attributes_for :recipe_steps, allow_destroy: true validates :name, presence: true - validates :yields, numericality: true, allow_blank: true validates :total_time, numericality: true, allow_blank: true validates :active_time, numericality: true, allow_blank: true @@ -61,6 +60,13 @@ class Recipe < ActiveRecord::Base @nutrition_data end + def parsed_yield + if @parsed_yield.nil? && self.yields.present? + @parsed_yield = YieldParser.parse(self.yields) + end + @parsed_yield + end + private def calculate_nutrition_data diff --git a/app/views/recipes/show.html.erb b/app/views/recipes/show.html.erb index dbc31cc..e828b12 100644 --- a/app/views/recipes/show.html.erb +++ b/app/views/recipes/show.html.erb @@ -92,31 +92,52 @@ Item + <% if @recipe.parsed_yield %> + <%= @recipe.parsed_yield.label %> + <% end %> Total Calories + <% if @recipe.parsed_yield %> + <%= @recipe.nutrition_data.kcal / @recipe.parsed_yield.number %> + <% end %> <%= @recipe.nutrition_data.kcal %> Grams Protein + <% if @recipe.parsed_yield %> + <%= @recipe.nutrition_data.protein / @recipe.parsed_yield.number %> + <% end %> <%= @recipe.nutrition_data.protein %> Grams Fat + <% if @recipe.parsed_yield %> + <%= @recipe.nutrition_data.lipids / @recipe.parsed_yield.number %> + <% end %> <%= @recipe.nutrition_data.lipids %> Grams Carbohydrates + <% if @recipe.parsed_yield %> + <%= @recipe.nutrition_data.carbohydrates / @recipe.parsed_yield.number %> + <% end %> <%= @recipe.nutrition_data.carbohydrates %> Grams Sugar + <% if @recipe.parsed_yield %> + <%= @recipe.nutrition_data.sugar / @recipe.parsed_yield.number %> + <% end %> <%= @recipe.nutrition_data.sugar %> Grams Fiber + <% if @recipe.parsed_yield %> + <%= @recipe.nutrition_data.fiber / @recipe.parsed_yield.number %> + <% end %> <%= @recipe.nutrition_data.fiber %> diff --git a/config/initializers/lib.rb b/config/initializers/lib.rb index 192a938..7b1286f 100644 --- a/config/initializers/lib.rb +++ b/config/initializers/lib.rb @@ -1,2 +1,3 @@ -require 'unit_conversion' \ No newline at end of file +require 'unit_conversion' +require 'yield_parser' \ No newline at end of file diff --git a/db/migrate/20160403205734_change_yields_col.rb b/db/migrate/20160403205734_change_yields_col.rb new file mode 100644 index 0000000..58809fe --- /dev/null +++ b/db/migrate/20160403205734_change_yields_col.rb @@ -0,0 +1,5 @@ +class ChangeYieldsCol < ActiveRecord::Migration + def change + change_column :recipes, :yields, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 816b8f7..675f142 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160311000203) do +ActiveRecord::Schema.define(version: 20160403205734) do create_table "ingredients", force: :cascade do |t| t.string "name" @@ -59,7 +59,7 @@ ActiveRecord::Schema.define(version: 20160311000203) do t.string "name" t.text "description" t.text "source" - t.integer "yields" + t.string "yields" t.integer "total_time" t.integer "active_time" t.datetime "created_at", null: false diff --git a/db/seeds.rb b/db/seeds.rb index 3e78b8c..e3ec115 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -10,28 +10,70 @@ require 'usda_importer' puts "Seeding..." -Ingredient.create!([ - {name: 'Water', density: '1 g/ml'}, - {name: 'Butter, Salted', density: '226 gram/cup', ndbn: '01001'}, - {name: 'Butter, Unsalted', density: '226 gram/cup'}, - {name: 'Flour, Bleached All Purpose', density: '130 gram/cup'}, - {name: 'Flour, Cake', density: '120 gram/cup'}, - {name: 'Flour, Whole Wheat', density: '130 gram/cup'}, - {name: 'Cornstarch', density: '10 gram/tablespoon'}, - {name: 'Cornmeal', density: '120 gram/cup'}, - {name: 'Sugar, Granulated', density: '200 gram/cup'}, - {name: 'Sugar, Brown, Lightly Packed', density: '210 gram/cup'}, - {name: 'Sugar, Powdered', density: '120 gram/cup'}, - {name: 'Chocolate Chips', density: '170 gram/cup'}, - {name: 'Cocoa Powder', density: '100 gram/cup'}, - {name: 'Salt, Kosher', density: '248 gram/cup'}, - {name: 'Salt, Table', density: '304 gram/cup'}, - {name: 'Milk, Whole', density: '1.028 gram/ml'}, - {name: 'Milk, Skim', density: '1.032 gram/ml'}, - {name: 'Milk, 2%', density: '1.03 gram/ml'} - ]) +dan = User.create!({username: 'dan', full_name: 'Dan', email: 'dan.elbert@gmail.com', password: 'qwerty', password_confirmation: 'qwerty'}) + +ingredients = { + water: {name: 'Water', density: '1 g/ml'}, + butter: {name: 'Butter, Salted', ndbn: '01001'}, + butter_sal: {name: 'Butter, Unsalted', density: '226 gram/cup'}, + flour: {name: 'Flour, Bleached All Purpose', density: '130 gram/cup'}, + flour_cake: {name: 'Flour, Cake', density: '120 gram/cup'}, + flour_wheat: {name: 'Flour, Whole Wheat', density: '130 gram/cup'}, + cornstarch: {name: 'Cornstarch', ndbn: '20027'}, + cornmeal: {name: 'Cornmeal', density: '120 gram/cup'}, + sugar: {name: 'Sugar, Granulated', ndbn: '19335'}, + sugar_brown: {name: 'Sugar, Brown, Lightly Packed', density: '210 gram/cup'}, + sugar_powder: {name: 'Sugar, Powdered', density: '120 gram/cup'}, + chips: {name: 'Chocolate Chips', density: '170 gram/cup'}, + cocoa: {name: 'Cocoa Powder', density: '100 gram/cup'}, + salt: {name: 'Salt, Kosher', density: '248 gram/cup'}, + table_salt: {name: 'Salt, Table', density: '304 gram/cup'}, + whole_milk: {name: 'Milk, Whole', density: '1.028 gram/ml'}, + skim_milk: {name: 'Milk, Skim', density: '1.032 gram/ml'}, + two_per_milk: {name: 'Milk, 2%', density: '1.03 gram/ml'} , + flank: {name: 'Flank Steak', ndbn: '13970'}, + soy_sauce: {name: 'Soy Sauce', ndbn: '16123'}, + shaoxing: {name: 'Shaoxing Wine', ndbn: '14084'}, + stock: {name: 'Chicken Stock, Low Sodium', ndbn: '06970'} , + oyster_sauce: {name: 'Oyster Sauce', ndbn: '06176'}, + seasame_oil: {name: 'Sesame Seed Oil', ndbn: '04058'} , + garlic: {name: 'Garlic', ndbn: '11215'}, + peanut_oil: {name: 'Peanut Oil', ndbn: '04042'}, + broccoli: {name: 'Broccoli Florets', ndbn: '11740'} + +} + +ingredients.each do |k, v| + ingredients[k] = Ingredient.create!({user_id: dan.id}.merge(v)) +end + +bb = Recipe.create!({ + name: 'Beef and Broccoli With Oyster Sauce', + source: 'http://www.seriouseats.com/recipes/2012/06/chinese-american-beef-and-broccoli-with-oyster-sauce-recipe.html', + yields: 4, + total_time: 30, + active_time: 10, + user_id: dan.id + }) + +[ + {quantity: '1', units: 'pound', preparation: 'flank steak, skirt steak, hanger steak, or flap meat, cut into 1/4-inch thick strips', ingredient: ingredients[:flank]}, + {quantity: '1/4', units: 'cup', preparation: 'divided', ingredient: ingredients[:soy_sauce]}, + {quantity: '1/4', units: 'cup', preparation: 'divided', ingredient: ingredients[:shaoxing]}, + {quantity: '2', units: 'teaspoons', preparation: '', ingredient: ingredients[:cornstarch]}, + {quantity: '1/3', units: 'cup', preparation: '', ingredient: ingredients[:stock]}, + {quantity: '1/4', units: 'cup', preparation: '', ingredient: ingredients[:oyster_sauce]}, + {quantity: '1', units: 'tablespoon', preparation: '', ingredient: ingredients[:sugar]}, + {quantity: '1', units: 'teaspoon', preparation: '', ingredient: ingredients[:seasame_oil]}, + {quantity: '2', units: 'medium cloves', preparation: 'finely minced', ingredient: ingredients[:garlic]}, + {quantity: '2', units: 'teaspoons', preparation: 'finely minced', name: 'ginger root'}, + {quantity: '3', units: '', preparation: 'whites finely sliced, greens cut into 1/2-inch segments, reserved separately', name: 'Scallions'}, + {quantity: '4', units: 'tablespoons', preparation: '', ingredient: ingredients[:peanut_oil]}, + {quantity: '1', units: 'pound', preparation: '', ingredient: ingredients[:broccoli]}, +].each_with_index do |ri, i| + RecipeIngredient.create!({recipe: bb, sort_order: i}.merge(ri)) +end -User.create!({username: 'dan', full_name: 'Dan', email: 'dan.elbert@gmail.com', password: 'qwerty', password_confirmation: 'qwerty'}) importer = UsdaImporter.new(Rails.root.join('vendor', 'data', 'usda')) importer.import diff --git a/lib/usda_importer.rb b/lib/usda_importer.rb index 7822f6c..bc8b483 100644 --- a/lib/usda_importer.rb +++ b/lib/usda_importer.rb @@ -190,6 +190,11 @@ class UsdaImporter sorted_files.each { |k, v| `rm #{v}` } end + Ingredient.where('ndbn != ?', '').where('ndbn IS NOT NULL').each do |i| + i.set_usda_food(i.usda_food) + i.save! + end + end def build_enumerator(opened_files) diff --git a/lib/yield_parser.rb b/lib/yield_parser.rb new file mode 100644 index 0000000..3d7cb24 --- /dev/null +++ b/lib/yield_parser.rb @@ -0,0 +1,19 @@ +class YieldParser + + Result = Struct.new(:number, :label) + + def self.parse(yield_string) + + match = /(\d+(?:\.\d*)?)\s*(\w[\w\s]*)?/.match(yield_string) + + case + when match.nil? + nil + when match[2] + Result.new(match[1].to_f, match[2].strip.singularize) + else + Result.new(match[1].to_f, 'each') + end + end + +end \ No newline at end of file diff --git a/spec/lib/yield_parser_spec.rb b/spec/lib/yield_parser_spec.rb new file mode 100644 index 0000000..5298251 --- /dev/null +++ b/spec/lib/yield_parser_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +RSpec.describe YieldParser do + + it 'parses various strings' do + expect(YieldParser.parse('4')).to eq YieldParser::Result.new(4.0, 'each') + expect(YieldParser.parse('4 servings')).to eq YieldParser::Result.new(4.0, 'serving') + expect(YieldParser.parse('3 pancakes')).to eq YieldParser::Result.new(3.0, 'pancake') + expect(YieldParser.parse('13.5 large croutons')).to eq YieldParser::Result.new(13.5, 'large crouton') + end + +end \ No newline at end of file