enhanced nutrition data

This commit is contained in:
Dan Elbert 2016-06-22 13:49:03 -05:00
parent 72ac0aab3b
commit 8811109351
11 changed files with 235 additions and 92 deletions

View File

@ -98,7 +98,7 @@ class RecipesController < ApplicationController
private private
# Use callbacks to share common setup or constraints between actions. # Use callbacks to share common setup or constraints between actions.
def set_recipe def set_recipe
@recipe = Recipe.find(params[:id]) @recipe = Recipe.includes(recipe_ingredients: :ingredient).find(params[:id])
end end
# Never trust parameters from the scary internet, only allow the white list through. # Never trust parameters from the scary internet, only allow the white list through.

View File

@ -1,6 +1,6 @@
class NutritionDataDecorator < BaseDecorator class NutritionDataDecorator < BaseDecorator
[:protein, :lipids, :carbohydrates, :kcal, :fiber, :sugar].each do |m| NutritionData::NUTRIENTS.each do |m|
def format_number(n) def format_number(n)
'%.1f' % n '%.1f' % n

View File

@ -22,4 +22,14 @@ module RecipesHelper
end end
}.compact.reverse.join(' ') }.compact.reverse.join(' ')
end end
def nutrient_row(recipe, nutrients, heading, nutrient_name)
content_tag('tr') do
[
content_tag('td', heading),
recipe.parsed_yield ? content_tag('td', nutrients.send("#{nutrient_name}_per".to_sym, recipe.parsed_yield.number)) : nil,
content_tag('td', nutrients.send("#{nutrient_name}".to_sym))
].compact.join("\n".html_safe).html_safe
end
end
end end

View File

@ -40,15 +40,38 @@ class Ingredient < ActiveRecord::Base
def set_usda_food(food) def set_usda_food(food)
return unless food return unless food
self.ndbn = food.ndbn copy_fields = [
self.water = food.water :water,
self.protein = food.protein :ash,
:protein,
:kcal,
:fiber,
:sugar,
:carbohydrates,
:calcium,
:iron,
:magnesium,
:phosphorus,
:potassium,
:sodium,
:zinc,
:copper,
:manganese,
:vit_c,
:vit_b6,
:vit_b12,
:vit_a,
:vit_e,
:vit_d,
:vit_k,
:cholesterol
]
copy_fields.each do |f|
self.send("#{f}=".to_sym, food.send(f.to_sym))
end
self.lipids = food.lipid self.lipids = food.lipid
self.carbohydrates = food.carbohydrates
self.ash = food.ash
self.kcal = food.kcal
self.fiber = food.fiber
self.sugar = food.sugar
self.density = food.density_best_guess self.density = food.density_best_guess
end end

View File

@ -1,15 +1,40 @@
class NutritionData class NutritionData
attr_reader :protein, :lipids, :carbohydrates, :kcal, :fiber, :sugar, :errors NUTRIENTS = [
:protein,
:lipids,
:kcal,
:fiber,
:sugar,
:carbohydrates,
:calcium,
:iron,
:magnesium,
:phosphorus,
:potassium,
:sodium,
:zinc,
:copper,
:manganese,
:vit_c,
:vit_b6,
:vit_b12,
:vit_a,
:vit_e,
:vit_d,
:vit_k,
:cholesterol
]
attr_reader :errors
attr_reader *NUTRIENTS
def initialize(recipe_ingredients) def initialize(recipe_ingredients)
@errors = [] @errors = []
@protein = 0.0
@lipids = 0.0 NUTRIENTS.each do |n|
@kcal = 0.0 self.instance_variable_set("@#{n}".to_sym, 0.0)
@fiber = 0.0 end
@sugar = 0.0
@carbohydrates = 0.0
valid_ingredients = [] valid_ingredients = []
@ -23,12 +48,10 @@ class NutritionData
end end
end end
keys = [:protein, :lipids, :kcal, :fiber, :sugar, :carbohydrates]
valid_ingredients.each do |i| valid_ingredients.each do |i|
grams = i.to_grams grams = i.to_grams
keys.each do |k| NUTRIENTS.each do |k|
value = i.ingredient.send(k) value = i.ingredient.send(k)
if value.present? if value.present?
value = value.to_f value = value.to_f
@ -41,7 +64,7 @@ class NutritionData
end end
end end
keys.each do |k| NUTRIENTS.each do |k|
v = self.instance_variable_get("@#{k}".to_sym) v = self.instance_variable_get("@#{k}".to_sym)
self.instance_variable_set("@#{k}".to_sym, v.round(2)) self.instance_variable_set("@#{k}".to_sym, v.round(2))
end end

View File

@ -42,6 +42,8 @@
<div class="panel-body"> <div class="panel-body">
<fieldset <%= 'disabled=disabled' if has_ndbn %>> <fieldset <%= 'disabled=disabled' if has_ndbn %>>
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="form-group"> <div class="form-group">
<%= f.label :water, "Grams of Water", class: 'control-label' %> <%= f.label :water, "Grams of Water", class: 'control-label' %>
<%= f.text_field :water, class: 'form-control' %> <%= f.text_field :water, class: 'form-control' %>
@ -76,6 +78,24 @@
<%= f.label :sugar, "Grams of Sugar", class: 'control-label' %> <%= f.label :sugar, "Grams of Sugar", class: 'control-label' %>
<%= f.text_field :sugar, class: 'form-control' %> <%= f.text_field :sugar, class: 'form-control' %>
</div> </div>
</div>
<div class="col-xs-12 col-md-6">
<div class="form-group">
<%= f.label :calcium, "Miligrams of Calcium", class: 'control-label' %>
<%= f.text_field :calcium, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :sodium, "Miligrams of Sodium", class: 'control-label' %>
<%= f.text_field :sodium, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :vit_k, "Micrograms of Vitamin K", class: 'control-label' %>
<%= f.text_field :vit_k, class: 'form-control' %>
</div>
</div>
</div>
</fieldset> </fieldset>
</div> </div>
</div> </div>

View File

@ -99,48 +99,16 @@
<th>Total</th> <th>Total</th>
</tr> </tr>
</thead> </thead>
<tr>
<td>Calories</td> <%= nutrient_row(@recipe, nutrition_data, 'Calories', :kcal) %>
<% if @recipe.parsed_yield %> <%= nutrient_row(@recipe, nutrition_data, 'g Protein', :protein) %>
<td><%= nutrition_data.kcal_per(@recipe.parsed_yield.number) %></td> <%= nutrient_row(@recipe, nutrition_data, 'g Fat', :lipids) %>
<% end %> <%= nutrient_row(@recipe, nutrition_data, 'g Carbohydrates', :carbohydrates) %>
<td><%= nutrition_data.kcal %></td> <%= nutrient_row(@recipe, nutrition_data, 'mg Sodium', :sodium) %>
</tr> <%= nutrient_row(@recipe, nutrition_data, 'g Sugar', :sugar) %>
<tr> <%= nutrient_row(@recipe, nutrition_data, 'g Fiber', :fiber) %>
<td>Grams Protein</td> <%= nutrient_row(@recipe, nutrition_data, 'µg Vitamin K', :vit_k) %>
<% if @recipe.parsed_yield %>
<td><%= nutrition_data.protein_per(@recipe.parsed_yield.number) %></td>
<% end %>
<td><%= nutrition_data.protein %></td>
</tr>
<tr>
<td>Grams Fat</td>
<% if @recipe.parsed_yield %>
<td><%= nutrition_data.lipids_per(@recipe.parsed_yield.number) %></td>
<% end %>
<td><%= nutrition_data.lipids %></td>
</tr>
<tr>
<td>Grams Carbohydrates</td>
<% if @recipe.parsed_yield %>
<td><%= nutrition_data.carbohydrates_per(@recipe.parsed_yield.number) %></td>
<% end %>
<td><%= nutrition_data.carbohydrates %></td>
</tr>
<tr>
<td>Grams Sugar</td>
<% if @recipe.parsed_yield %>
<td><%= nutrition_data.sugar_per(@recipe.parsed_yield.number) %></td>
<% end %>
<td><%= nutrition_data.sugar %></td>
</tr>
<tr>
<td>Grams Fiber</td>
<% if @recipe.parsed_yield %>
<td><%= nutrition_data.fiber_per(@recipe.parsed_yield.number) %></td>
<% end %>
<td><%= nutrition_data.fiber %></td>
</tr>
</table> </table>
<% end %> <% end %>

View File

@ -0,0 +1,24 @@
class AddNutrientsToUsdaFoods < ActiveRecord::Migration
def change
change_table 'usda_foods' do |t|
t.integer :calcium
t.decimal :iron, precision: 10, scale: 2
t.integer :magnesium
t.integer :phosphorus
t.integer :potassium
t.integer :sodium
t.decimal :zinc, precision: 10, scale: 2
t.decimal :copper, precision: 10, scale: 3
t.decimal :manganese, precision: 10, scale: 3
t.decimal :vit_c, precision: 10, scale: 1
t.decimal :vit_b6, precision: 10, scale: 3
t.decimal :vit_b12, precision: 10, scale: 2
t.integer :vit_a
t.decimal :vit_e, precision: 10, scale: 2
t.decimal :vit_d, precision: 10, scale: 1
t.decimal :vit_k, precision: 10, scale: 1
t.decimal :cholesterol, precision: 10, scale: 3
end
end
end

View File

@ -0,0 +1,24 @@
class AddNutrientsToIngredients < ActiveRecord::Migration
def change
change_table 'ingredients' do |t|
t.integer :calcium
t.decimal :iron, precision: 10, scale: 2
t.integer :magnesium
t.integer :phosphorus
t.integer :potassium
t.integer :sodium
t.decimal :zinc, precision: 10, scale: 2
t.decimal :copper, precision: 10, scale: 3
t.decimal :manganese, precision: 10, scale: 3
t.decimal :vit_c, precision: 10, scale: 1
t.decimal :vit_b6, precision: 10, scale: 3
t.decimal :vit_b12, precision: 10, scale: 2
t.integer :vit_a
t.decimal :vit_e, precision: 10, scale: 2
t.decimal :vit_d, precision: 10, scale: 1
t.decimal :vit_k, precision: 10, scale: 1
t.decimal :cholesterol, precision: 10, scale: 3
end
end
end

View File

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160403205734) do ActiveRecord::Schema.define(version: 20160622180838) do
create_table "ingredients", force: :cascade do |t| create_table "ingredients", force: :cascade do |t|
t.string "name" t.string "name"
@ -29,6 +29,23 @@ ActiveRecord::Schema.define(version: 20160403205734) do
t.decimal "fiber", precision: 10, scale: 1 t.decimal "fiber", precision: 10, scale: 1
t.decimal "sugar", precision: 10, scale: 2 t.decimal "sugar", precision: 10, scale: 2
t.integer "user_id" t.integer "user_id"
t.integer "calcium"
t.decimal "iron", precision: 10, scale: 2
t.integer "magnesium"
t.integer "phosphorus"
t.integer "potassium"
t.integer "sodium"
t.decimal "zinc", precision: 10, scale: 2
t.decimal "copper", precision: 10, scale: 3
t.decimal "manganese", precision: 10, scale: 3
t.decimal "vit_c", precision: 10, scale: 1
t.decimal "vit_b6", precision: 10, scale: 3
t.decimal "vit_b12", precision: 10, scale: 2
t.integer "vit_a"
t.decimal "vit_e", precision: 10, scale: 2
t.decimal "vit_d", precision: 10, scale: 1
t.decimal "vit_k", precision: 10, scale: 1
t.decimal "cholesterol", precision: 10, scale: 3
end end
create_table "recipe_ingredients", force: :cascade do |t| create_table "recipe_ingredients", force: :cascade do |t|
@ -100,6 +117,23 @@ ActiveRecord::Schema.define(version: 20160403205734) do
t.string "scientific_name" t.string "scientific_name"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.integer "calcium"
t.decimal "iron", precision: 10, scale: 2
t.integer "magnesium"
t.integer "phosphorus"
t.integer "potassium"
t.integer "sodium"
t.decimal "zinc", precision: 10, scale: 2
t.decimal "copper", precision: 10, scale: 3
t.decimal "manganese", precision: 10, scale: 3
t.decimal "vit_c", precision: 10, scale: 1
t.decimal "vit_b6", precision: 10, scale: 3
t.decimal "vit_b12", precision: 10, scale: 2
t.integer "vit_a"
t.decimal "vit_e", precision: 10, scale: 2
t.decimal "vit_d", precision: 10, scale: 1
t.decimal "vit_k", precision: 10, scale: 1
t.decimal "cholesterol", precision: 10, scale: 3
end end
add_index "usda_foods", ["long_description"], name: "index_usda_foods_on_long_description" add_index "usda_foods", ["long_description"], name: "index_usda_foods_on_long_description"

View File

@ -75,7 +75,24 @@ class UsdaImporter
gram_weight_2: 'GmWt_2', gram_weight_2: 'GmWt_2',
gram_weight_desc_1: 'GmWt_Desc1', gram_weight_desc_1: 'GmWt_Desc1',
gram_weight_desc_2: 'GmWt_Desc2', gram_weight_desc_2: 'GmWt_Desc2',
refuse_percent: 'Refuse_Pct' refuse_percent: 'Refuse_Pct',
calcium: 'Calcium',
iron: 'Iron',
magnesium: 'Magnesium',
phosphorus: 'Phosphorus',
potassium: 'Potassium',
sodium: 'Sodium',
zinc: 'Zinc',
copper: 'Copper',
manganese: 'Manganese',
vit_c: 'Vit_C',
vit_b6: 'Vit_B6',
vit_b12: 'Vit_B12',
vit_a: 'Vit_A_RAE',
vit_e: 'Vit_E',
vit_d: 'Vit_D_mcg',
vit_k: 'Vit_K',
cholesterol: 'Cholestrl'
} }
}, },