Added usda food data
This commit is contained in:
parent
f434900291
commit
9f04a65e19
@ -3,4 +3,29 @@ class Ingredient < ActiveRecord::Base
|
|||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :density, density: true, allow_blank: true
|
validates :density, density: true, allow_blank: true
|
||||||
|
|
||||||
|
def set_usda_food(food)
|
||||||
|
self.ndbn = food.ndbn
|
||||||
|
self.density = calculate_density(food.gram_weight_1, food.gram_weight_desc_1) || calculate_density(food.gram_weight_2, food.gram_weight_desc_2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def calculate_density(grams, description)
|
||||||
|
return nil if grams.blank? || description.blank?
|
||||||
|
|
||||||
|
# replace 'fl oz' with 'floz'
|
||||||
|
description = description.gsub(/fl oz/i, 'floz')
|
||||||
|
|
||||||
|
begin
|
||||||
|
unit = UnitConversion.parse(description)
|
||||||
|
if UnitConversion.volume?(unit)
|
||||||
|
mass = Unitwise(grams, 'g')
|
||||||
|
density = (mass / unit).convert_to(UnitConversion.normalize_unit_names('oz/cup'))
|
||||||
|
return "#{density.value.round(4)} oz/cup"
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
rescue UnitConversion::UnparseableUnitError
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -15,6 +15,7 @@ module UnitConversion
|
|||||||
'[pt_us]': %w(pint pints),
|
'[pt_us]': %w(pint pints),
|
||||||
'[qt_us]': %w(quart quarts qt),
|
'[qt_us]': %w(quart quarts qt),
|
||||||
'[gal_us]': %w(gallon gallons ga),
|
'[gal_us]': %w(gallon gallons ga),
|
||||||
|
'[foz_us]': %w(foz floz),
|
||||||
|
|
||||||
g: %w(gram grams),
|
g: %w(gram grams),
|
||||||
kg: %w(kilograms kilogram),
|
kg: %w(kilograms kilogram),
|
||||||
|
3
app/models/usda_food.rb
Normal file
3
app/models/usda_food.rb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class UsdaFood < ActiveRecord::Base
|
||||||
|
|
||||||
|
end
|
25
db/migrate/20160124212254_create_usda_food.rb
Normal file
25
db/migrate/20160124212254_create_usda_food.rb
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
class CreateUsdaFood < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :usda_foods do |t|
|
||||||
|
|
||||||
|
t.string :ndbn, limit: 5, index: true, null: false
|
||||||
|
|
||||||
|
t.string :short_description
|
||||||
|
t.decimal :water, precision: 10, scale: 2
|
||||||
|
t.integer :kcal
|
||||||
|
t.decimal :protein, precision: 10, scale: 2
|
||||||
|
t.decimal :lipid, precision: 10, scale: 2
|
||||||
|
t.decimal :ash, precision: 10, scale: 2
|
||||||
|
t.decimal :carbohydrates, precision: 10, scale: 2
|
||||||
|
t.decimal :fiber, precision: 10, scale: 1
|
||||||
|
t.decimal :sugar, precision: 10, scale: 2
|
||||||
|
t.decimal :gram_weight_1, precision: 9, scale: 2
|
||||||
|
t.decimal :gram_weight_2, precision: 9, scale: 2
|
||||||
|
t.string :gram_weight_desc_1
|
||||||
|
t.string :gram_weight_desc_2
|
||||||
|
t.integer :refuse_percent
|
||||||
|
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
8
db/migrate/20160124222409_add_ndbn_to_ingredients.rb
Normal file
8
db/migrate/20160124222409_add_ndbn_to_ingredients.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
class AddNdbnToIngredients < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
change_table :ingredients do |t|
|
||||||
|
t.string :ndbn, limit: 5, index: true
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
db/schema.rb
29
db/schema.rb
@ -11,14 +11,15 @@
|
|||||||
#
|
#
|
||||||
# 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: 20160119212055) do
|
ActiveRecord::Schema.define(version: 20160124222409) do
|
||||||
|
|
||||||
create_table "ingredients", force: :cascade do |t|
|
create_table "ingredients", force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "density"
|
t.string "density"
|
||||||
t.text "notes"
|
t.text "notes"
|
||||||
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.string "ndbn", limit: 5
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "recipe_ingredients", force: :cascade do |t|
|
create_table "recipe_ingredients", force: :cascade do |t|
|
||||||
@ -58,6 +59,28 @@ ActiveRecord::Schema.define(version: 20160119212055) do
|
|||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "usda_foods", force: :cascade do |t|
|
||||||
|
t.string "ndbn", limit: 5, null: false
|
||||||
|
t.string "short_description"
|
||||||
|
t.decimal "water", precision: 10, scale: 2
|
||||||
|
t.integer "kcal"
|
||||||
|
t.decimal "protein", precision: 10, scale: 2
|
||||||
|
t.decimal "lipid", precision: 10, scale: 2
|
||||||
|
t.decimal "ash", precision: 10, scale: 2
|
||||||
|
t.decimal "carbohydrates", precision: 10, scale: 2
|
||||||
|
t.decimal "fiber", precision: 10, scale: 1
|
||||||
|
t.decimal "sugar", precision: 10, scale: 2
|
||||||
|
t.decimal "gram_weight_1", precision: 9, scale: 2
|
||||||
|
t.decimal "gram_weight_2", precision: 9, scale: 2
|
||||||
|
t.string "gram_weight_desc_1"
|
||||||
|
t.string "gram_weight_desc_2"
|
||||||
|
t.integer "refuse_percent"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "usda_foods", ["ndbn"], name: "index_usda_foods_on_ndbn"
|
||||||
|
|
||||||
create_table "users", force: :cascade do |t|
|
create_table "users", force: :cascade do |t|
|
||||||
t.string "username"
|
t.string "username"
|
||||||
t.string "email"
|
t.string "email"
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
|
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
|
||||||
# Mayor.create(name: 'Emanuel', city: cities.first)
|
# Mayor.create(name: 'Emanuel', city: cities.first)
|
||||||
|
|
||||||
|
require 'usda_importer'
|
||||||
|
|
||||||
puts "Seeding..."
|
puts "Seeding..."
|
||||||
|
|
||||||
Ingredient.create!([
|
Ingredient.create!([
|
||||||
{name: 'Water', density: '1 g/ml'},
|
{name: 'Water', density: '1 g/ml'},
|
||||||
{name: 'Butter, Salted', density: '226 gram/cup'},
|
{name: 'Butter, Salted', density: '226 gram/cup', ndbn: '01001'},
|
||||||
{name: 'Butter, Unsalted', density: '226 gram/cup'},
|
{name: 'Butter, Unsalted', density: '226 gram/cup'},
|
||||||
{name: 'Flour, Bleached All Purpose', density: '130 gram/cup'},
|
{name: 'Flour, Bleached All Purpose', density: '130 gram/cup'},
|
||||||
{name: 'Flour, Cake', density: '120 gram/cup'},
|
{name: 'Flour, Cake', density: '120 gram/cup'},
|
||||||
@ -30,6 +31,8 @@ Ingredient.create!([
|
|||||||
{name: 'Milk, 2%', density: '1.03 gram/ml'}
|
{name: 'Milk, 2%', density: '1.03 gram/ml'}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
importer = UsdaImporter.new(Rails.root.join('vendor', 'data', 'usda', 'ABBREV.txt'))
|
||||||
|
importer.import
|
||||||
|
|
||||||
|
|
||||||
puts "Seeds planted."
|
puts "Seeds planted."
|
118
lib/usda_importer.rb
Normal file
118
lib/usda_importer.rb
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
require 'csv'
|
||||||
|
|
||||||
|
class UsdaImporter
|
||||||
|
|
||||||
|
COLUMNS = [
|
||||||
|
'NDB_No',
|
||||||
|
'Shrt_Desc',
|
||||||
|
'Water',
|
||||||
|
'Energ_Kcal',
|
||||||
|
'Protein',
|
||||||
|
'Lipid_Tot',
|
||||||
|
'Ash',
|
||||||
|
'Carbohydrt',
|
||||||
|
'Fiber_TD',
|
||||||
|
'Sugar_Tot',
|
||||||
|
'Calcium',
|
||||||
|
'Iron',
|
||||||
|
'Magnesium',
|
||||||
|
'Phosphorus',
|
||||||
|
'Potassium',
|
||||||
|
'Sodium',
|
||||||
|
'Zinc',
|
||||||
|
'Copper',
|
||||||
|
'Manganese',
|
||||||
|
'Selenium',
|
||||||
|
'Vit_C',
|
||||||
|
'Thiamin',
|
||||||
|
'Riboflavin',
|
||||||
|
'Niacin',
|
||||||
|
'Panto_acid',
|
||||||
|
'Vit_B6',
|
||||||
|
'Folate_Tot',
|
||||||
|
'Folic_acid',
|
||||||
|
'Food_Folate',
|
||||||
|
'Folate_DFE',
|
||||||
|
'Choline_Tot',
|
||||||
|
'Vit_B12',
|
||||||
|
'Vit_A_IU',
|
||||||
|
'Vit_A_RAE',
|
||||||
|
'Retinol',
|
||||||
|
'Alpha_Carot',
|
||||||
|
'Beta_Carot',
|
||||||
|
'Beta_Crypt',
|
||||||
|
'Lycopene',
|
||||||
|
'Lut+Zea',
|
||||||
|
'Vit_E',
|
||||||
|
'Vit_D_mcg',
|
||||||
|
'Vit_D_IU',
|
||||||
|
'Vit_K',
|
||||||
|
'FA_Sat',
|
||||||
|
'FA_Mono',
|
||||||
|
'FA_Poly',
|
||||||
|
'Cholestrl',
|
||||||
|
'GmWt_1',
|
||||||
|
'GmWt_Desc1',
|
||||||
|
'GmWt_2',
|
||||||
|
'GmWt_Desc2',
|
||||||
|
'Refuse_Pct'
|
||||||
|
]
|
||||||
|
|
||||||
|
COLUMN_MAP = {
|
||||||
|
ndbn: 'NDB_No',
|
||||||
|
short_description: 'Shrt_Desc',
|
||||||
|
water: 'Water',
|
||||||
|
kcal: 'Energ_Kcal',
|
||||||
|
protein: 'Protein',
|
||||||
|
lipid: 'Lipid_Tot',
|
||||||
|
ash: 'Ash',
|
||||||
|
carbohydrates: 'Carbohydrt',
|
||||||
|
fiber: 'Fiber_TD',
|
||||||
|
sugar: 'Sugar_Tot',
|
||||||
|
gram_weight_1: 'GmWt_1',
|
||||||
|
gram_weight_2: 'GmWt_2',
|
||||||
|
gram_weight_desc_1: 'GmWt_Desc1',
|
||||||
|
gram_weight_desc_2: 'GmWt_Desc2',
|
||||||
|
refuse_percent: 'Refuse_Pct'
|
||||||
|
}
|
||||||
|
|
||||||
|
def initialize(file)
|
||||||
|
@file = file
|
||||||
|
end
|
||||||
|
|
||||||
|
def import
|
||||||
|
|
||||||
|
UsdaFood.delete_all
|
||||||
|
|
||||||
|
CSV.open(@file, 'r:iso-8859-1:utf-8', csv_options) do |csv|
|
||||||
|
csv.each_slice(500) do |slice|
|
||||||
|
UsdaFood.transaction do
|
||||||
|
|
||||||
|
attributes = slice.map do |row|
|
||||||
|
Hash[COLUMN_MAP.map { |db, col| [db, row[col]] }]
|
||||||
|
end
|
||||||
|
|
||||||
|
UsdaFood.create(attributes)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
usda_items = Hash[UsdaFood.where(ndbn: Ingredient.select(:ndbn)).map { |uf| [uf.ndbn, uf] }]
|
||||||
|
|
||||||
|
Ingredient.where('ndbn IS NOT NULL').each do |i|
|
||||||
|
item = usda_items[i.ndbn]
|
||||||
|
|
||||||
|
if item
|
||||||
|
i.set_usda_food(item)
|
||||||
|
i.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def csv_options
|
||||||
|
{ col_sep: '^', quote_char: '~', headers: COLUMNS }
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
8789
vendor/data/usda/ABBREV.txt
vendored
Normal file
8789
vendor/data/usda/ABBREV.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/data/usda/sr28_doc.pdf
vendored
Normal file
BIN
vendor/data/usda/sr28_doc.pdf
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user