Added long descirption to usda foods
This commit is contained in:
parent
70e7a8b415
commit
2dca779294
@ -95,7 +95,7 @@ class IngredientsController < ApplicationController
|
||||
end
|
||||
|
||||
def usda_food_search
|
||||
@foods = UsdaFood.search(params[:query]).limit(50)
|
||||
@foods = UsdaFood.search(params[:query]).limit(50).order(:long_description)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :layout => false }
|
||||
|
@ -7,7 +7,7 @@ class UsdaFood < ActiveRecord::Base
|
||||
if tokens.empty?
|
||||
UsdaFood.none
|
||||
else
|
||||
UsdaFood.matches_tokens(:short_description, tokens)
|
||||
UsdaFood.matches_tokens(:long_description, tokens)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
<span class="glyphicon glyphicon-link"></span><span class="ndbn"><%= @ingredient.ndbn %></span>
|
||||
</button>
|
||||
</div>
|
||||
<p class="form-control-static" style="padding-left: 7px;"><%= @ingredient.ndbn ? UsdaFood.find_by_ndbn(@ingredient.ndbn).short_description : '' %></p>
|
||||
<p class="form-control-static" style="padding-left: 7px;"><%= @ingredient.ndbn ? UsdaFood.find_by_ndbn(@ingredient.ndbn).long_description : '' %></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
<tr>
|
||||
<th><%= f.ndbn %></th>
|
||||
<th><%= link_to f.short_description, '#', class: 'food_result', data: {ndbn: f.ndbn} %></th>
|
||||
<th><%= link_to f.long_description, '#', class: 'food_result', data: {ndbn: f.ndbn} %></th>
|
||||
</tr>
|
||||
|
||||
<% end %>
|
||||
|
@ -2,6 +2,6 @@
|
||||
json.array! @foods do |f|
|
||||
|
||||
json.extract! f, :ndbn
|
||||
json.name f.short_description
|
||||
json.name f.long_description
|
||||
|
||||
end
|
@ -3,8 +3,8 @@ class CreateUsdaFood < ActiveRecord::Migration
|
||||
create_table :usda_foods do |t|
|
||||
|
||||
t.string :ndbn, limit: 5, index: :unique, null: false
|
||||
|
||||
t.string :short_description, index: true
|
||||
t.string :long_description, index: true
|
||||
t.string :short_description
|
||||
t.decimal :water, precision: 10, scale: 2
|
||||
t.integer :kcal
|
||||
t.decimal :protein, precision: 10, scale: 2
|
||||
@ -17,7 +17,9 @@ class CreateUsdaFood < ActiveRecord::Migration
|
||||
t.decimal :gram_weight_2, precision: 9, scale: 2
|
||||
t.string :gram_weight_desc_1
|
||||
t.string :gram_weight_desc_2
|
||||
t.string :refuse_description
|
||||
t.integer :refuse_percent
|
||||
t.string :scientific_name
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
|
@ -69,6 +69,7 @@ ActiveRecord::Schema.define(version: 20160124231837) do
|
||||
|
||||
create_table "usda_foods", force: :cascade do |t|
|
||||
t.string "ndbn", limit: 5, null: false
|
||||
t.string "long_description"
|
||||
t.string "short_description"
|
||||
t.decimal "water", precision: 10, scale: 2
|
||||
t.integer "kcal"
|
||||
@ -82,13 +83,15 @@ ActiveRecord::Schema.define(version: 20160124231837) do
|
||||
t.decimal "gram_weight_2", precision: 9, scale: 2
|
||||
t.string "gram_weight_desc_1"
|
||||
t.string "gram_weight_desc_2"
|
||||
t.string "refuse_description"
|
||||
t.integer "refuse_percent"
|
||||
t.string "scientific_name"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_index "usda_foods", ["long_description"], name: "index_usda_foods_on_long_description"
|
||||
add_index "usda_foods", ["ndbn"], name: "index_usda_foods_on_ndbn"
|
||||
add_index "usda_foods", ["short_description"], name: "index_usda_foods_on_short_description"
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "username"
|
||||
|
@ -33,7 +33,7 @@ Ingredient.create!([
|
||||
|
||||
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', 'ABBREV.txt'))
|
||||
importer = UsdaImporter.new(Rails.root.join('vendor', 'data', 'usda'))
|
||||
importer.import
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@ namespace :usda do
|
||||
|
||||
desc 'Empties usda_foods table, imports all data, and then updates any linked ingredients'
|
||||
task import: :environment do
|
||||
importer = UsdaImporter.new(Rails.root.join('vendor', 'data', 'usda', 'ABBREV.txt'))
|
||||
importer = UsdaImporter.new(Rails.root.join('vendor', 'data', 'usda'))
|
||||
importer.import
|
||||
end
|
||||
end
|
@ -2,7 +2,7 @@ require 'csv'
|
||||
|
||||
class UsdaImporter
|
||||
|
||||
COLUMNS = [
|
||||
ABBREV_COLUMNS = [
|
||||
'NDB_No',
|
||||
'Shrt_Desc',
|
||||
'Water',
|
||||
@ -58,7 +58,24 @@ class UsdaImporter
|
||||
'Refuse_Pct'
|
||||
]
|
||||
|
||||
COLUMN_MAP = {
|
||||
FOOD_DATA_COLUMNS = [
|
||||
'NDB_No',
|
||||
'FdGrp_Cd',
|
||||
'Long_Desc',
|
||||
'Shrt_Desc',
|
||||
'ComName',
|
||||
'ManufacName',
|
||||
'Survey',
|
||||
'Ref_desc',
|
||||
'Refuse',
|
||||
'SciName',
|
||||
'N_Factor',
|
||||
'Pro_Factor',
|
||||
'Fat_Factor',
|
||||
'CHO_Factor'
|
||||
]
|
||||
|
||||
ABBREV_COLUMN_MAP = {
|
||||
ndbn: 'NDB_No',
|
||||
short_description: 'Shrt_Desc',
|
||||
water: 'Water',
|
||||
@ -76,20 +93,40 @@ class UsdaImporter
|
||||
refuse_percent: 'Refuse_Pct'
|
||||
}
|
||||
|
||||
def initialize(file)
|
||||
@file = file
|
||||
FOOD_DATA_COLUMN_MAP = {
|
||||
scientific_name: 'SciName',
|
||||
refuse_description: 'Ref_desc',
|
||||
long_description: 'Long_Desc'
|
||||
}
|
||||
|
||||
def initialize(directory)
|
||||
@directory = directory
|
||||
end
|
||||
|
||||
def import
|
||||
|
||||
UsdaFood.delete_all
|
||||
|
||||
CSV.open(@file, 'r:iso-8859-1:utf-8', csv_options) do |csv|
|
||||
food_data_lookup = {}
|
||||
|
||||
CSV.open(File.join(@directory, 'FOOD_DES.txt'), 'r:iso-8859-1:utf-8', csv_options(FOOD_DATA_COLUMNS)) do |csv|
|
||||
csv.each do |row|
|
||||
food_data_lookup[row['NDB_No']] = row.to_h
|
||||
end
|
||||
end
|
||||
|
||||
CSV.open(File.join(@directory, 'ABBREV.txt'), 'r:iso-8859-1:utf-8', csv_options(ABBREV_COLUMNS)) 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]] }]
|
||||
attrs = Hash[ABBREV_COLUMN_MAP.map { |db, col| [db, row[col]] }]
|
||||
lookup = food_data_lookup[attrs[:ndbn]]
|
||||
if lookup
|
||||
extra_attrs = Hash[FOOD_DATA_COLUMN_MAP.map { |db, col| [db, lookup[col]] }]
|
||||
attrs.merge!(extra_attrs)
|
||||
end
|
||||
attrs
|
||||
end
|
||||
|
||||
UsdaFood.create(attributes)
|
||||
@ -111,8 +148,8 @@ class UsdaImporter
|
||||
|
||||
end
|
||||
|
||||
def csv_options
|
||||
{ col_sep: '^', quote_char: '~', headers: COLUMNS }
|
||||
def csv_options(headers)
|
||||
{ col_sep: '^', quote_char: '~', headers: headers }
|
||||
end
|
||||
|
||||
end
|
@ -5,6 +5,7 @@ FactoryGirl.define do
|
||||
end
|
||||
|
||||
factory :usda_food do
|
||||
long_description 'Food'
|
||||
short_description 'Food'
|
||||
ndbn '01234'
|
||||
water 1.0
|
||||
|
@ -4,11 +4,11 @@ RSpec.describe UsdaFood do
|
||||
|
||||
let!(:data) do
|
||||
{
|
||||
salted_butter: create(:usda_food, short_description: 'Salted Butter'),
|
||||
unsalted_butter: create(:usda_food, short_description: 'Unsalted Butter'),
|
||||
flour: create(:usda_food, short_description: 'Flour'),
|
||||
bread_flour: create(:usda_food, short_description: 'Bread Flour'),
|
||||
sugar: create(:usda_food, short_description: 'Sugar,Granulated')
|
||||
salted_butter: create(:usda_food, long_description: 'Salted Butter'),
|
||||
unsalted_butter: create(:usda_food, long_description: 'Unsalted Butter'),
|
||||
flour: create(:usda_food, long_description: 'Flour'),
|
||||
bread_flour: create(:usda_food, long_description: 'Bread Flour'),
|
||||
sugar: create(:usda_food, long_description: 'Sugar,Granulated')
|
||||
}
|
||||
end
|
||||
|
||||
@ -17,23 +17,23 @@ RSpec.describe UsdaFood do
|
||||
end
|
||||
|
||||
it 'can be found by single tokens' do
|
||||
r = UsdaFood.matches_tokens(:short_description, ['sal'])
|
||||
r = UsdaFood.matches_tokens(:long_description, ['sal'])
|
||||
expect(r.length).to eq 1
|
||||
expect(r).to contain_exactly *items(:salted_butter)
|
||||
|
||||
r = UsdaFood.matches_tokens(:short_description, ['flour'])
|
||||
r = UsdaFood.matches_tokens(:long_description, ['flour'])
|
||||
expect(r.length).to eq 2
|
||||
expect(r).to contain_exactly *items(:flour, :bread_flour)
|
||||
end
|
||||
|
||||
it 'can be found by multiple tokens' do
|
||||
r = UsdaFood.matches_tokens(:short_description, ['sal', 'butter'])
|
||||
r = UsdaFood.matches_tokens(:long_description, ['sal', 'butter'])
|
||||
expect(r.length).to eq 1
|
||||
expect(r).to contain_exactly *items(:salted_butter)
|
||||
end
|
||||
|
||||
it 'treats commas like spaces' do
|
||||
r = UsdaFood.matches_tokens(:short_description, ['gran', 'sugar'])
|
||||
r = UsdaFood.matches_tokens(:long_description, ['gran', 'sugar'])
|
||||
expect(r.length).to eq 1
|
||||
expect(r).to contain_exactly *items(:sugar)
|
||||
end
|
||||
|
8789
vendor/data/usda/FOOD_DES.txt
vendored
Normal file
8789
vendor/data/usda/FOOD_DES.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user