Added long descirption to usda foods
This commit is contained in:
parent
70e7a8b415
commit
2dca779294
@ -95,7 +95,7 @@ class IngredientsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def usda_food_search
|
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|
|
respond_to do |format|
|
||||||
format.html { render :layout => false }
|
format.html { render :layout => false }
|
||||||
|
@ -7,7 +7,7 @@ class UsdaFood < ActiveRecord::Base
|
|||||||
if tokens.empty?
|
if tokens.empty?
|
||||||
UsdaFood.none
|
UsdaFood.none
|
||||||
else
|
else
|
||||||
UsdaFood.matches_tokens(:short_description, tokens)
|
UsdaFood.matches_tokens(:long_description, tokens)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<span class="glyphicon glyphicon-link"></span><span class="ndbn"><%= @ingredient.ndbn %></span>
|
<span class="glyphicon glyphicon-link"></span><span class="ndbn"><%= @ingredient.ndbn %></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th><%= f.ndbn %></th>
|
<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>
|
</tr>
|
||||||
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
json.array! @foods do |f|
|
json.array! @foods do |f|
|
||||||
|
|
||||||
json.extract! f, :ndbn
|
json.extract! f, :ndbn
|
||||||
json.name f.short_description
|
json.name f.long_description
|
||||||
|
|
||||||
end
|
end
|
@ -3,8 +3,8 @@ class CreateUsdaFood < ActiveRecord::Migration
|
|||||||
create_table :usda_foods do |t|
|
create_table :usda_foods do |t|
|
||||||
|
|
||||||
t.string :ndbn, limit: 5, index: :unique, null: false
|
t.string :ndbn, limit: 5, index: :unique, null: false
|
||||||
|
t.string :long_description, index: true
|
||||||
t.string :short_description, index: true
|
t.string :short_description
|
||||||
t.decimal :water, precision: 10, scale: 2
|
t.decimal :water, precision: 10, scale: 2
|
||||||
t.integer :kcal
|
t.integer :kcal
|
||||||
t.decimal :protein, precision: 10, scale: 2
|
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.decimal :gram_weight_2, precision: 9, scale: 2
|
||||||
t.string :gram_weight_desc_1
|
t.string :gram_weight_desc_1
|
||||||
t.string :gram_weight_desc_2
|
t.string :gram_weight_desc_2
|
||||||
|
t.string :refuse_description
|
||||||
t.integer :refuse_percent
|
t.integer :refuse_percent
|
||||||
|
t.string :scientific_name
|
||||||
|
|
||||||
t.timestamps null: false
|
t.timestamps null: false
|
||||||
end
|
end
|
||||||
|
@ -69,6 +69,7 @@ ActiveRecord::Schema.define(version: 20160124231837) do
|
|||||||
|
|
||||||
create_table "usda_foods", force: :cascade do |t|
|
create_table "usda_foods", force: :cascade do |t|
|
||||||
t.string "ndbn", limit: 5, null: false
|
t.string "ndbn", limit: 5, null: false
|
||||||
|
t.string "long_description"
|
||||||
t.string "short_description"
|
t.string "short_description"
|
||||||
t.decimal "water", precision: 10, scale: 2
|
t.decimal "water", precision: 10, scale: 2
|
||||||
t.integer "kcal"
|
t.integer "kcal"
|
||||||
@ -82,13 +83,15 @@ ActiveRecord::Schema.define(version: 20160124231837) do
|
|||||||
t.decimal "gram_weight_2", precision: 9, scale: 2
|
t.decimal "gram_weight_2", precision: 9, scale: 2
|
||||||
t.string "gram_weight_desc_1"
|
t.string "gram_weight_desc_1"
|
||||||
t.string "gram_weight_desc_2"
|
t.string "gram_weight_desc_2"
|
||||||
|
t.string "refuse_description"
|
||||||
t.integer "refuse_percent"
|
t.integer "refuse_percent"
|
||||||
|
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
|
||||||
end
|
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", ["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|
|
create_table "users", force: :cascade do |t|
|
||||||
t.string "username"
|
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'})
|
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
|
importer.import
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ namespace :usda do
|
|||||||
|
|
||||||
desc 'Empties usda_foods table, imports all data, and then updates any linked ingredients'
|
desc 'Empties usda_foods table, imports all data, and then updates any linked ingredients'
|
||||||
task import: :environment do
|
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
|
importer.import
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -2,7 +2,7 @@ require 'csv'
|
|||||||
|
|
||||||
class UsdaImporter
|
class UsdaImporter
|
||||||
|
|
||||||
COLUMNS = [
|
ABBREV_COLUMNS = [
|
||||||
'NDB_No',
|
'NDB_No',
|
||||||
'Shrt_Desc',
|
'Shrt_Desc',
|
||||||
'Water',
|
'Water',
|
||||||
@ -57,8 +57,25 @@ class UsdaImporter
|
|||||||
'GmWt_Desc2',
|
'GmWt_Desc2',
|
||||||
'Refuse_Pct'
|
'Refuse_Pct'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
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'
|
||||||
|
]
|
||||||
|
|
||||||
COLUMN_MAP = {
|
ABBREV_COLUMN_MAP = {
|
||||||
ndbn: 'NDB_No',
|
ndbn: 'NDB_No',
|
||||||
short_description: 'Shrt_Desc',
|
short_description: 'Shrt_Desc',
|
||||||
water: 'Water',
|
water: 'Water',
|
||||||
@ -76,20 +93,40 @@ class UsdaImporter
|
|||||||
refuse_percent: 'Refuse_Pct'
|
refuse_percent: 'Refuse_Pct'
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize(file)
|
FOOD_DATA_COLUMN_MAP = {
|
||||||
@file = file
|
scientific_name: 'SciName',
|
||||||
|
refuse_description: 'Ref_desc',
|
||||||
|
long_description: 'Long_Desc'
|
||||||
|
}
|
||||||
|
|
||||||
|
def initialize(directory)
|
||||||
|
@directory = directory
|
||||||
end
|
end
|
||||||
|
|
||||||
def import
|
def import
|
||||||
|
|
||||||
UsdaFood.delete_all
|
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|
|
csv.each_slice(500) do |slice|
|
||||||
UsdaFood.transaction do
|
UsdaFood.transaction do
|
||||||
|
|
||||||
attributes = slice.map do |row|
|
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
|
end
|
||||||
|
|
||||||
UsdaFood.create(attributes)
|
UsdaFood.create(attributes)
|
||||||
@ -111,8 +148,8 @@ class UsdaImporter
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def csv_options
|
def csv_options(headers)
|
||||||
{ col_sep: '^', quote_char: '~', headers: COLUMNS }
|
{ col_sep: '^', quote_char: '~', headers: headers }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -5,6 +5,7 @@ FactoryGirl.define do
|
|||||||
end
|
end
|
||||||
|
|
||||||
factory :usda_food do
|
factory :usda_food do
|
||||||
|
long_description 'Food'
|
||||||
short_description 'Food'
|
short_description 'Food'
|
||||||
ndbn '01234'
|
ndbn '01234'
|
||||||
water 1.0
|
water 1.0
|
||||||
|
@ -4,11 +4,11 @@ RSpec.describe UsdaFood do
|
|||||||
|
|
||||||
let!(:data) do
|
let!(:data) do
|
||||||
{
|
{
|
||||||
salted_butter: create(:usda_food, short_description: 'Salted Butter'),
|
salted_butter: create(:usda_food, long_description: 'Salted Butter'),
|
||||||
unsalted_butter: create(:usda_food, short_description: 'Unsalted Butter'),
|
unsalted_butter: create(:usda_food, long_description: 'Unsalted Butter'),
|
||||||
flour: create(:usda_food, short_description: 'Flour'),
|
flour: create(:usda_food, long_description: 'Flour'),
|
||||||
bread_flour: create(:usda_food, short_description: 'Bread Flour'),
|
bread_flour: create(:usda_food, long_description: 'Bread Flour'),
|
||||||
sugar: create(:usda_food, short_description: 'Sugar,Granulated')
|
sugar: create(:usda_food, long_description: 'Sugar,Granulated')
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -17,23 +17,23 @@ RSpec.describe UsdaFood do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'can be found by single tokens' do
|
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.length).to eq 1
|
||||||
expect(r).to contain_exactly *items(:salted_butter)
|
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.length).to eq 2
|
||||||
expect(r).to contain_exactly *items(:flour, :bread_flour)
|
expect(r).to contain_exactly *items(:flour, :bread_flour)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can be found by multiple tokens' do
|
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.length).to eq 1
|
||||||
expect(r).to contain_exactly *items(:salted_butter)
|
expect(r).to contain_exactly *items(:salted_butter)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'treats commas like spaces' do
|
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.length).to eq 1
|
||||||
expect(r).to contain_exactly *items(:sugar)
|
expect(r).to contain_exactly *items(:sugar)
|
||||||
end
|
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