class NutritionData attr_reader :protein, :lipids, :carbohydrates, :kcal, :fiber, :sugar, :errors def initialize(recipe_ingredients) @errors = [] @protein = 0.0 @lipids = 0.0 @kcal = 0.0 @fiber = 0.0 @sugar = 0.0 @carbohydrates = 0.0 valid_ingredients = [] recipe_ingredients.each do |i| if i.ingredient_id.nil? @errors << "#{i.name} has no nutrition data" elsif !i.can_convert_to_grams? @errors << "#{i.name} can't be converted to grams" else valid_ingredients << i end end keys = [:protein, :lipids, :kcal, :fiber, :sugar, :carbohydrates] valid_ingredients.each do |i| grams = i.to_grams keys.each do |k| value = i.ingredient.send(k) if value.present? value = value.to_f running_total = self.instance_variable_get("@#{k}".to_sym) delta = (grams / 100.0) * value self.instance_variable_set("@#{k}".to_sym, running_total + delta) else @errors << "#{i.name} missing #{k} data" end end end keys.each do |k| v = self.instance_variable_get("@#{k}".to_sym) self.instance_variable_set("@#{k}".to_sym, v.round(2)) end end end