diff --git a/app/controllers/logs_controller.rb b/app/controllers/logs_controller.rb
index 695475a..3c629f6 100644
--- a/app/controllers/logs_controller.rb
+++ b/app/controllers/logs_controller.rb
@@ -48,7 +48,7 @@ class LogsController < ApplicationController
@log.source_recipe = @recipe
if @log.save
- render json: { success: true }
+ render json: { id: @log.id }
else
render json: @log.errors, status: :unprocessable_entity
end
diff --git a/app/controllers/recipes_controller.rb b/app/controllers/recipes_controller.rb
index d04e22b..fd58a9c 100644
--- a/app/controllers/recipes_controller.rb
+++ b/app/controllers/recipes_controller.rb
@@ -48,7 +48,7 @@ class RecipesController < ApplicationController
@recipe.user = current_user
if @recipe.save
- render json: { success: true }
+ render json: { id: @recipe.id }
else
render json: @recipe.errors, status: :unprocessable_entity
end
diff --git a/app/javascript/components/TheFoodCreator.vue b/app/javascript/components/TheFoodCreator.vue
index 5114b71..9f464e9 100644
--- a/app/javascript/components/TheFoodCreator.vue
+++ b/app/javascript/components/TheFoodCreator.vue
@@ -4,7 +4,7 @@
- Cancel
+ Cancel
diff --git a/app/javascript/components/TheLogCreator.vue b/app/javascript/components/TheLogCreator.vue
index f09599c..fa89acb 100644
--- a/app/javascript/components/TheLogCreator.vue
+++ b/app/javascript/components/TheLogCreator.vue
@@ -8,11 +8,6 @@
-
-
- Cancel
-
-
@@ -51,7 +46,7 @@
loadResource(
api.postLog(log)
- .then(() => router.push('/'))
+ .then(data => router.push({ name: 'log', params: { id: data.id } }))
.catch(Errors.onlyFor(Errors.ApiValidationError, err => validationErrors.value = err.validationErrors()))
);
}
diff --git a/app/javascript/components/TheLogEditor.vue b/app/javascript/components/TheLogEditor.vue
index 09b583e..588772a 100644
--- a/app/javascript/components/TheLogEditor.vue
+++ b/app/javascript/components/TheLogEditor.vue
@@ -8,11 +8,6 @@
-
-
- Cancel
-
-
@@ -45,7 +40,7 @@
validationErrors.value = {};
loadResource(
api.patchLog(log.value)
- .then(() => router.push('/'))
+ .then(() => router.push({ name: 'log', params: { id: log.value.id } }))
.catch(Errors.onlyFor(Errors.ApiValidationError, err => validationErrors.value = err.validationErrors()))
);
}
diff --git a/app/javascript/components/TheRecipeCreator.vue b/app/javascript/components/TheRecipeCreator.vue
index f8a0a3d..68b7ed6 100644
--- a/app/javascript/components/TheRecipeCreator.vue
+++ b/app/javascript/components/TheRecipeCreator.vue
@@ -42,7 +42,7 @@
validationErrors.value = {};
loadResource(
api.postRecipe(recipe.value)
- .then(() => router.push('/'))
+ .then(data => router.push({ name: 'recipe', params: { id: data.id } }))
.catch(Errors.onlyFor(Errors.ApiValidationError, err => validationErrors.value = err.validationErrors()))
);
}
diff --git a/lib/usda_importer.rb b/lib/usda_importer.rb
index 849e505..bc0cb78 100644
--- a/lib/usda_importer.rb
+++ b/lib/usda_importer.rb
@@ -378,49 +378,62 @@ class UsdaImporter
end
build_enumerator(opened_files).each_slice(500) do |slice|
- UsdaFood.transaction do
- slice.each do |data|
+ now = Time.current
+ food_attrs = []
+ weight_groups = []
- food = UsdaFood.new
+ slice.each do |data|
+ food = UsdaFood.new
+ weight_hashes = []
- data.each do |name, rows|
- file_info = FILES[name]
- obj = food
-
- rows.each do |row|
- if file_info[:map_into]
- obj = food.send(file_info[:map_into]).build
- end
-
- if file_info[:static]
- file_info[:static].each do |k, v|
- obj.send("#{k}=", v)
- end
- end
+ data.each do |name, rows|
+ file_info = FILES[name]
+ rows.each do |row|
+ if file_info[:map_into]
+ w = {}
+ file_info[:static]&.each { |k, v| w[k.to_s] = v }
+ file_info[:map].each { |db, col| w[db.to_s] = row[col] }
+ weight_hashes << w
+ else
+ file_info[:static]&.each { |k, v| food.send("#{k}=", v) }
if file_info[:map_function]
- file_info[:map_function].call(obj, row)
+ file_info[:map_function].call(food, row)
else
- file_info[:map].each do |db, col|
- obj.send("#{db}=", row[col])
- end
+ file_info[:map].each { |db, col| food.send("#{db}=", row[col]) }
end
end
end
+ end
- food.save!
+ attrs = food.attributes.except('id')
+ attrs['created_at'] = now
+ attrs['updated_at'] = now
+ food_attrs << attrs
+ weight_groups << weight_hashes
+ end
+ result = UsdaFood.insert_all!(food_attrs, returning: %w[id ndbn])
+ id_idx = result.columns.index('id')
+ ndbn_idx = result.columns.index('ndbn')
+ ndbn_to_id = result.rows.each_with_object({}) { |row, h| h[row[ndbn_idx]] = row[id_idx] }
+
+ all_weights = []
+ food_attrs.each_with_index do |fa, i|
+ food_id = ndbn_to_id[fa['ndbn']]
+ weight_groups[i].each do |w|
+ all_weights << w.merge('usda_food_id' => food_id, 'created_at' => now, 'updated_at' => now)
end
end
+ UsdaFoodWeight.insert_all!(all_weights) if all_weights.any?
end
-
ensure
opened_files.each { |k, v| v.close }
sorted_files.each { |k, v| `rm #{v}` }
end
- Food.where('ndbn != ?', '').where('ndbn IS NOT NULL').each do |i|
+ Food.where('ndbn != ?', '').where('ndbn IS NOT NULL').find_each do |i|
i.set_usda_food(i.usda_food)
i.save!
end
@@ -444,7 +457,7 @@ class UsdaImporter
loop do
break if enumerate_data.values.all? { |d| d[:done] }
- current_ndbn = enumerate_data.select { |_, d| !d[:done] }.values.map { |d| d[:next_ndbn] }.min
+ current_ndbn = enumerate_data.select { |_, d| !d[:done] }.values.min_by { |d| d[:next_ndbn].to_i }[:next_ndbn]
results = Hash.new { |hash, key| hash[key] = [] }
enumerate_data.each do |name, data|
diff --git a/spec/lib/usda_importer_spec.rb b/spec/lib/usda_importer_spec.rb
index 40c4088..37e3a10 100644
--- a/spec/lib/usda_importer_spec.rb
+++ b/spec/lib/usda_importer_spec.rb
@@ -3,19 +3,45 @@ require 'usda_importer'
RSpec.describe UsdaImporter do
- it 'imports' do
- i = UsdaImporter.new(Rails.root.join('spec', 'test_data'))
- i.import
+ subject(:import) { UsdaImporter.new(Rails.root.join('spec', 'test_data')).import }
+
+ it 'imports the correct number of foods with weights' do
+ import
expect(UsdaFood.count).to eq 5
- butter = UsdaFood.where(ndbn: '01001').first
+
+ butter = UsdaFood.find_by(ndbn: '01001')
expect(butter).not_to be_nil
expect(butter.usda_food_weights.count).to eq 4
- clif_bar = UsdaFood.where(ndbn: '45042066').first
+ clif_bar = UsdaFood.find_by(ndbn: '45042066')
expect(clif_bar).not_to be_nil
expect(clif_bar.usda_food_weights.count).to eq 1
+ end
+
+ it 'imports SR28 nutrition fields correctly' do
+ import
+
+ butter = UsdaFood.find_by(ndbn: '01001')
+ expect(butter.kcal).to eq 717
+ expect(butter.protein).to eq 0.85
+ expect(butter.source).to eq 'sr'
+ end
+
+ it 'imports branded nutrition fields via map_function' do
+ import
+
+ clif_bar = UsdaFood.find_by(ndbn: '45042066')
expect(clif_bar.kcal).to eq 368
+ expect(clif_bar.protein).to eq 13.24
+ expect(clif_bar.source).to eq 'bf'
+ end
+
+ it 'updates linked Food records with usda nutrition data' do
+ food = create(:food, ndbn: '01001')
+ import
+ food.reload
+ expect(food.kcal).to eq 717
end
end