class NutritionData NUTRIENTS = { protein: 'g Protein', lipids: 'g Fat', kcal: 'Calories', fiber: 'g Fiber', sugar: 'g Sugar', carbohydrates: 'g Carbohydrates', calcium: nil, iron: nil, magnesium: nil, phosphorus: nil, potassium: nil, sodium: 'mg Sodium', zinc: nil, copper: nil, manganese: nil, vit_c: nil, vit_b6: nil, vit_b12: nil, vit_a: nil, vit_e: nil, vit_d: nil, vit_k: 'µg Vitamin K', cholesterol: nil } attr_reader :errors attr_reader *NUTRIENTS.keys def initialize(recipe_ingredients) @errors = [] NUTRIENTS.keys.each do |n| self.instance_variable_set("@#{n}".to_sym, 0.0) end recipe_ingredients.each do |i| if i.ingredient.nil? || i.ingredient.nutrition_data.nil? @errors << "#{i.name} has no nutrition data" next end nutrient_scale = i.calculate_nutrition_ratio if nutrient_scale.nil? @errors << "#{i.name} has an unknown quantity or unit" next end unless i.ingredient.nutrition_errors.empty? @errors << "#{i.name}: #{i.ingredient.nutrition_errors.join(", ")}" end missing = [] NUTRIENTS.each do |k, n| value = i.ingredient.nutrition_data.send(k) if value.present? value = value.to_f running_total = self.instance_variable_get("@#{k}".to_sym) delta = value * nutrient_scale self.instance_variable_set("@#{k}".to_sym, running_total + delta) else missing << k end end missing = missing.map { |k| NUTRIENTS[k] }.compact unless missing.empty? @errors << "#{i.name} missing the following nutrients: #{missing.join(', ')}" end end end end