From 8e8160c41ade42b586b0830f8412a247230714a6 Mon Sep 17 00:00:00 2001 From: cryptogopher Date: Tue, 14 Apr 2020 19:44:19 +0200 Subject: [PATCH] Renamed Ingredient -> Food Ingredient is now part of composition (meal/recipe/dish) --- app/controllers/concerns/finders.rb | 6 +- ...ents_controller.rb => foods_controller.rb} | 70 +++++++++---------- app/controllers/meals_controller.rb | 2 +- ...{ingredients_helper.rb => foods_helper.rb} | 10 +-- app/models/{ingredient.rb => food.rb} | 4 +- app/models/meal.rb | 6 ++ app/models/nutrient.rb | 4 +- app/views/foods/_contextual.html.erb | 6 ++ .../_edit_form.html.erb | 8 +-- .../{ingredients => foods}/_filters.html.erb | 6 +- .../{ingredients => foods}/_form.html.erb | 6 +- .../{ingredients => foods}/_import.html.erb | 9 ++- .../{ingredients => foods}/_index.html.erb | 30 ++++---- app/views/foods/_new_form.html.erb | 18 +++++ .../_nutrients.html.erb | 28 ++++---- .../{ingredients => foods}/_options.html.erb | 2 +- app/views/foods/create.js.erb | 6 ++ app/views/foods/destroy.js.erb | 3 + app/views/foods/edit.js.erb | 8 +++ app/views/foods/index.html.erb | 15 ++++ app/views/foods/index.js.erb | 5 ++ app/views/foods/new.js.erb | 2 + app/views/foods/nutrients.html.erb | 15 ++++ app/views/foods/toggle.js.erb | 1 + app/views/foods/toggle_column.js.erb | 1 + app/views/ingredients/_contextual.html.erb | 6 -- app/views/ingredients/_new_form.html.erb | 18 ----- app/views/ingredients/create.js.erb | 6 -- app/views/ingredients/destroy.js.erb | 3 - app/views/ingredients/edit.js.erb | 8 --- app/views/ingredients/index.html.erb | 15 ---- app/views/ingredients/index.js.erb | 5 -- app/views/ingredients/new.js.erb | 2 - app/views/ingredients/nutrients.html.erb | 15 ---- app/views/ingredients/toggle.js.erb | 1 - app/views/ingredients/toggle_column.js.erb | 1 - app/views/layouts/_sidebar.html.erb | 4 +- assets/stylesheets/body_tracking.css | 2 +- config/locales/en.yml | 22 +++--- config/routes.rb | 2 +- db/migrate/001_create_schema.rb | 8 +-- init.rb | 4 +- lib/body_tracking/items_with_quantities.rb | 4 +- lib/body_tracking/project_patch.rb | 2 +- ...oller_test.rb => foods_controller_test.rb} | 2 +- .../unit/{ingredient_test.rb => food_test.rb} | 2 +- 46 files changed, 204 insertions(+), 199 deletions(-) rename app/controllers/{ingredients_controller.rb => foods_controller.rb} (71%) rename app/helpers/{ingredients_helper.rb => foods_helper.rb} (79%) rename app/models/{ingredient.rb => food.rb} (91%) create mode 100644 app/views/foods/_contextual.html.erb rename app/views/{ingredients => foods}/_edit_form.html.erb (52%) rename app/views/{ingredients => foods}/_filters.html.erb (91%) rename app/views/{ingredients => foods}/_form.html.erb (93%) rename app/views/{ingredients => foods}/_import.html.erb (56%) rename app/views/{ingredients => foods}/_index.html.erb (51%) create mode 100644 app/views/foods/_new_form.html.erb rename app/views/{ingredients => foods}/_nutrients.html.erb (75%) rename app/views/{ingredients => foods}/_options.html.erb (87%) create mode 100644 app/views/foods/create.js.erb create mode 100644 app/views/foods/destroy.js.erb create mode 100644 app/views/foods/edit.js.erb create mode 100644 app/views/foods/index.html.erb create mode 100644 app/views/foods/index.js.erb create mode 100644 app/views/foods/new.js.erb create mode 100644 app/views/foods/nutrients.html.erb create mode 100644 app/views/foods/toggle.js.erb create mode 100644 app/views/foods/toggle_column.js.erb delete mode 100644 app/views/ingredients/_contextual.html.erb delete mode 100644 app/views/ingredients/_new_form.html.erb delete mode 100644 app/views/ingredients/create.js.erb delete mode 100644 app/views/ingredients/destroy.js.erb delete mode 100644 app/views/ingredients/edit.js.erb delete mode 100644 app/views/ingredients/index.html.erb delete mode 100644 app/views/ingredients/index.js.erb delete mode 100644 app/views/ingredients/new.js.erb delete mode 100644 app/views/ingredients/nutrients.html.erb delete mode 100644 app/views/ingredients/toggle.js.erb delete mode 100644 app/views/ingredients/toggle_column.js.erb rename test/functional/{ingredients_controller_test.rb => foods_controller_test.rb} (69%) rename test/unit/{ingredient_test.rb => food_test.rb} (74%) diff --git a/app/controllers/concerns/finders.rb b/app/controllers/concerns/finders.rb index ea0eae5..643d4c7 100644 --- a/app/controllers/concerns/finders.rb +++ b/app/controllers/concerns/finders.rb @@ -1,9 +1,9 @@ module Concerns::Finders private - def find_ingredient - @ingredient = Ingredient.find(params[:id]) - @project = @ingredient.project + def find_food + @food = Food.find(params[:id]) + @project = @food.project rescue ActiveRecord::RecordNotFound render_404 end diff --git a/app/controllers/ingredients_controller.rb b/app/controllers/foods_controller.rb similarity index 71% rename from app/controllers/ingredients_controller.rb rename to app/controllers/foods_controller.rb index 491369e..bbacaff 100644 --- a/app/controllers/ingredients_controller.rb +++ b/app/controllers/foods_controller.rb @@ -1,4 +1,4 @@ -class IngredientsController < ApplicationController +class FoodsController < ApplicationController require 'csv' layout 'body_tracking' @@ -11,25 +11,25 @@ class IngredientsController < ApplicationController before_action :find_project_by_project_id, only: [:index, :new, :create, :nutrients, :filter, :import] before_action :find_quantity_by_quantity_id, only: [:toggle_column] - before_action :find_ingredient, only: [:edit, :update, :destroy, :toggle] + before_action :find_food, only: [:edit, :update, :destroy, :toggle] before_action :authorize def index - prepare_ingredients + prepare_foods end def new - @ingredient = @project.ingredients.new - @ingredient.nutrients.new(unit: @ingredient.ref_unit) + @food = @project.foods.new + @food.nutrients.new(unit: @food.ref_unit) end def create - @ingredient = @project.ingredients.new(ingredient_params) - if @ingredient.save - flash[:notice] = 'Created new ingredient' + @food = @project.foods.new(food_params) + if @food.save + flash[:notice] = 'Created new food' prepare_items else - @ingredient.nutrients.new(unit: @ingredient.ref_unit) if @ingredient.nutrients.empty? + @food.nutrients.new(unit: @food.ref_unit) if @food.nutrients.empty? render :new end end @@ -38,8 +38,8 @@ class IngredientsController < ApplicationController end def update - if @ingredient.update(ingredient_params) - flash[:notice] = 'Updated ingredient' + if @food.update(food_params) + flash[:notice] = 'Updated food' prepare_items render :index else @@ -48,13 +48,13 @@ class IngredientsController < ApplicationController end def destroy - if @ingredient.destroy - flash[:notice] = 'Deleted ingredient' + if @food.destroy + flash[:notice] = 'Deleted food' end end def toggle - @ingredient.toggle_hidden! + @food.toggle_hidden! prepare_items end @@ -68,7 +68,7 @@ class IngredientsController < ApplicationController end def filter - session[:i_filters] = params.permit(:name, :visibility, formula: [:code, :zero_nil]) + session[:f_filters] = params.permit(:name, :visibility, formula: [:code, :zero_nil]) prepare_items render :index end @@ -80,7 +80,7 @@ class IngredientsController < ApplicationController quantities = @project.quantities.diet.map { |q| [q.name, q] }.to_h units = @project.units.map { |u| [u.shortname, u] }.to_h sources = @project.sources.map { |s| [s.name, s] }.to_h - ingredients_params = [] + foods_params = [] column_units = {} CSV.foreach(params[:file].path, headers: true).with_index(2) do |row, line| @@ -92,7 +92,7 @@ class IngredientsController < ApplicationController warnings << "Line #{line}: unknown source name #{r['Source']}" end - i_params = { + f_params = { name: r.delete('Name'), notes: r.delete('Notes'), ref_amount: 100.0, @@ -138,12 +138,12 @@ class IngredientsController < ApplicationController next if quantities[quantity].blank? if quantity == 'Reference' - i_params.update({ + f_params.update({ ref_amount: amount.to_d, ref_unit: unit }) else - i_params[:nutrients_attributes] << { + f_params[:nutrients_attributes] << { quantity: quantities[quantity], amount: amount.to_d, unit: unit @@ -151,20 +151,20 @@ class IngredientsController < ApplicationController end end - ingredients_params << i_params + foods_params << f_params end else warnings << 'No file selected' end if warnings.empty? - ingredients = @project.ingredients.create(ingredients_params) - flash[:notice] = "Imported #{ingredients.map(&:persisted?).count(true)} out of" \ - " #{ingredients_params.length} ingredients" - skipped = ingredients.select { |i| !i.persisted? } + foods = @project.foods.create(foods_params) + flash[:notice] = "Imported #{foods.map(&:persisted?).count(true)} out of" \ + " #{foods_params.length} foods" + skipped = foods.select { |f| !f.persisted? } if skipped.length > 0 - skipped_desc = skipped.map { |i| "#{i.name} - #{i.errors.full_messages.join(', ')}" } - flash[:warning] = "Ingredients skipped due to errors:
" \ + skipped_desc = skipped.map { |f| "#{f.name} - #{f.errors.full_messages.join(', ')}" } + flash[:warning] = "Foods skipped due to errors:
" \ " #{skipped_desc.join('
').truncate(1024)}" end else @@ -177,11 +177,11 @@ class IngredientsController < ApplicationController private def init_session_filters - session[:i_filters] ||= {formula: {}} + session[:f_filters] ||= {formula: {}} end - def ingredient_params - params.require(:ingredient).permit( + def food_params + params.require(:food).permit( :name, :notes, :ref_amount, @@ -201,18 +201,18 @@ class IngredientsController < ApplicationController end def prepare_items - params[:view] == 'index' ? prepare_ingredients : prepare_nutrients + params[:view] == 'index' ? prepare_foods : prepare_nutrients end - def prepare_ingredients - @ingredients, @formula_q = @project.ingredients + def prepare_foods + @foods, @formula_q = @project.foods .includes(:ref_unit, :source) - .filter(session[:i_filters]) + .filter(session[:f_filters]) end def prepare_nutrients @quantities = @project.nutrient_quantities.includes(:formula) - @ingredients, @requested_n, @extra_n, @formula_q = @project.ingredients - .filter(session[:i_filters], @quantities) + @foods, @requested_n, @extra_n, @formula_q = @project.foods + .filter(session[:f_filters], @quantities) end end diff --git a/app/controllers/meals_controller.rb b/app/controllers/meals_controller.rb index 89ab654..cc81507 100644 --- a/app/controllers/meals_controller.rb +++ b/app/controllers/meals_controller.rb @@ -16,6 +16,6 @@ class MealsController < ApplicationController private def prepare_meals - @meals = @project.meals.includes(:ingredients) + @meals = @project.meals.includes(:foods) end end diff --git a/app/helpers/ingredients_helper.rb b/app/helpers/foods_helper.rb similarity index 79% rename from app/helpers/ingredients_helper.rb rename to app/helpers/foods_helper.rb index a84dca4..5254c53 100644 --- a/app/helpers/ingredients_helper.rb +++ b/app/helpers/foods_helper.rb @@ -1,4 +1,4 @@ -module IngredientsHelper +module FoodsHelper def quantity_options nested_set_options(@project.quantities.diet) do |q| raw("#{' ' * q.level}#{q.name}") @@ -28,14 +28,14 @@ module IngredientsHelper def group_options translations = t('.groups') - Ingredient.groups.map do |k,v| + Food.groups.map do |k,v| [translations[k.to_sym], k] end end - def action_links(i, view) - link_to(l(:button_edit), edit_ingredient_path(i, view: view), + def action_links(f, view) + link_to(l(:button_edit), edit_food_path(f, view: view), {remote: true, class: "icon icon-edit"}) + - delete_link(ingredient_path(i), {remote: true, data: {}}) + delete_link(food_path(f), {remote: true, data: {}}) end end diff --git a/app/models/ingredient.rb b/app/models/food.rb similarity index 91% rename from app/models/ingredient.rb rename to app/models/food.rb index c7d4c09..f06490d 100644 --- a/app/models/ingredient.rb +++ b/app/models/food.rb @@ -1,4 +1,4 @@ -class Ingredient < ActiveRecord::Base +class Food < ActiveRecord::Base enum group: { other: 0, dish: 1, @@ -16,7 +16,7 @@ class Ingredient < ActiveRecord::Base belongs_to :ref_unit, class_name: 'Unit', required: true belongs_to :source, required: false - has_many :nutrients, inverse_of: :ingredient, dependent: :destroy, validate: true + has_many :nutrients, inverse_of: :food, dependent: :destroy, validate: true validates :nutrients, presence: true accepts_nested_attributes_for :nutrients, allow_destroy: true, reject_if: proc { |attrs| attrs['quantity_id'].blank? && attrs['amount'].blank? diff --git a/app/models/meal.rb b/app/models/meal.rb index e69de29..9e5bd52 100644 --- a/app/models/meal.rb +++ b/app/models/meal.rb @@ -0,0 +1,6 @@ +class Meal < ActiveRecord::Base + belongs_to :project, required: true + + has_many :ingredients, as: :composition, dependent: :destroy + has_many :foods, through: :ingredients +end diff --git a/app/models/nutrient.rb b/app/models/nutrient.rb index 836ea29..418e4f7 100644 --- a/app/models/nutrient.rb +++ b/app/models/nutrient.rb @@ -1,8 +1,8 @@ class Nutrient < ActiveRecord::Base - belongs_to :ingredient, inverse_of: :nutrients, required: true + belongs_to :food, inverse_of: :nutrients, required: true belongs_to :quantity, required: true belongs_to :unit, required: true - validates :quantity, uniqueness: {scope: :ingredient_id} + validates :quantity, uniqueness: {scope: :food_id} validates :amount, numericality: {greater_than_or_equal_to: 0.0} end diff --git a/app/views/foods/_contextual.html.erb b/app/views/foods/_contextual.html.erb new file mode 100644 index 0000000..aeef49b --- /dev/null +++ b/app/views/foods/_contextual.html.erb @@ -0,0 +1,6 @@ +<% if User.current.allowed_to?(:manage_common, @project) %> + <%= link_to t(".link_import_foods"), '#', class: 'icon icon-multiple', + onclick: '$("#import-foods").show(); $("#filename").focus(); return false;' %> + <%= link_to t(".link_new_food"), new_project_food_path(@project, view: view), + {remote: true, class: 'icon icon-add'} %> +<% end %> diff --git a/app/views/ingredients/_edit_form.html.erb b/app/views/foods/_edit_form.html.erb similarity index 52% rename from app/views/ingredients/_edit_form.html.erb rename to app/views/foods/_edit_form.html.erb index 945191c..da1d05f 100644 --- a/app/views/ingredients/_edit_form.html.erb +++ b/app/views/foods/_edit_form.html.erb @@ -1,9 +1,9 @@ -<%= labelled_form_for @ingredient, - url: ingredient_path(@ingredient, view: view), +<%= labelled_form_for @food, + url: food_path(@food, view: view), method: :patch, remote: true, - html: {id: 'ingredient-edit-form', name: 'ingredient-edit-form'} do |f| %> + html: {id: 'food-edit-form', name: 'food-edit-form'} do |f| %> - <%= render partial: 'ingredients/form', locals: {f: f} %> + <%= render partial: 'foods/form', locals: {f: f} %>

diff --git a/app/views/ingredients/_filters.html.erb b/app/views/foods/_filters.html.erb similarity index 91% rename from app/views/ingredients/_filters.html.erb rename to app/views/foods/_filters.html.erb index 6d6ce81..dd6348b 100644 --- a/app/views/ingredients/_filters.html.erb +++ b/app/views/foods/_filters.html.erb @@ -9,14 +9,14 @@ diff --git a/app/views/ingredients/_form.html.erb b/app/views/foods/_form.html.erb similarity index 93% rename from app/views/ingredients/_form.html.erb rename to app/views/foods/_form.html.erb index 679747e..58caaf5 100644 --- a/app/views/ingredients/_form.html.erb +++ b/app/views/foods/_form.html.erb @@ -1,4 +1,4 @@ -<%= error_messages_for @ingredient %> +<%= error_messages_for @food %>

<%= f.text_field :name, size: 40, required: true %>

@@ -21,7 +21,7 @@

<%= f.text_field :source_ident, size: 25, required: false %>

- <% @ingredient.nutrients.each_with_index do |n, index| %> + <% @food.nutrients.each_with_index do |n, index| %> <%= f.fields_for 'nutrients_attributes', n, index: '' do |ff| %>

<%= ff.hidden_field :id %> @@ -32,7 +32,7 @@ <%= ff.hidden_field :_destroy %> <%= link_to t(".button_delete_nutrient"), '#', class: 'icon icon-del', - style: (@ingredient.nutrients.length > 1 ? "" : "display:none"), + style: (@food.nutrients.length > 1 ? "" : "display:none"), onclick: "deleteNutrient(); return false;" %>

<% end %> diff --git a/app/views/ingredients/_import.html.erb b/app/views/foods/_import.html.erb similarity index 56% rename from app/views/ingredients/_import.html.erb rename to app/views/foods/_import.html.erb index 99cdd25..06d7484 100644 --- a/app/views/ingredients/_import.html.erb +++ b/app/views/foods/_import.html.erb @@ -1,7 +1,7 @@ -
- <%= text_field_tag 'name', session[:i_filters][:name], placeholder: 'name' %> + <%= text_field_tag 'name', session[:f_filters][:name], placeholder: 'name' %> - <%= select_tag 'visibility', visibility_options(session[:i_filters][:visibility]), + <%= select_tag 'visibility', visibility_options(session[:f_filters][:visibility]), prompt: t('.visibility_prompt'), onchange: '$("#filters-form").submit();' %> - <%= text_field_tag 'formula[code]', session[:i_filters][:formula][:code], + <%= text_field_tag 'formula[code]', session[:f_filters][:formula][:code], placeholder: 'conditional expression including nutrients', size: 40, style: 'box-sizing:border-box; width:100%;' %>
@@ -16,26 +16,26 @@ - <% @ingredients.each do |i| %> - <% next if i.new_record? %> - + <% @foods.each do |f| %> + <% next if f.new_record? %> + - - - + + + - + <% end %> diff --git a/app/views/foods/_new_form.html.erb b/app/views/foods/_new_form.html.erb new file mode 100644 index 0000000..5efae9b --- /dev/null +++ b/app/views/foods/_new_form.html.erb @@ -0,0 +1,18 @@ +

<%= t ".heading_new_food" %>

+ +<%= labelled_form_for @food, + url: project_foods_path(@project, view: view), + remote: true, + html: {id: 'new-food-form', name: 'new-food-form'} do |f| %> + + <%= render partial: 'foods/form', locals: {f: f} %> + +
+

+ <%= submit_tag l(:button_create) %> + <%= link_to l(:button_cancel), "#", + onclick: '$("#new-food").empty(); return false;' %> +

+
+<% end %> +
diff --git a/app/views/ingredients/_nutrients.html.erb b/app/views/foods/_nutrients.html.erb similarity index 75% rename from app/views/ingredients/_nutrients.html.erb rename to app/views/foods/_nutrients.html.erb index 6364a7f..a2c7d0b 100644 --- a/app/views/ingredients/_nutrients.html.erb +++ b/app/views/foods/_nutrients.html.erb @@ -1,8 +1,8 @@ -<%= render partial: 'ingredients/filters', - locals: {url: filter_project_ingredients_path(@project, view: :nutrients)} %> +<%= render partial: 'foods/filters', + locals: {url: filter_project_foods_path(@project, view: :nutrients)} %> -<% if @ingredients.any? %> - <%= render partial: 'ingredients/options' %> +<% if @foods.any? %> + <%= render partial: 'foods/options' %> <% formulas = @quantities.map { |q| q.formula } %> <% formulas.unshift(@formula_q.formula) if @formula_q %> @@ -17,7 +17,7 @@ - <% @ingredients.each_with_index do |i, index| %> - <% row_class = "ingredient#{' hidden' if i.hidden} #{cycle('odd', 'even')}" %> - + <% @foods.each_with_index do |f, index| %> + <% row_class = "food#{' hidden' if f.hidden} #{cycle('odd', 'even')}" %> + <% @requested_n[index].each do |*, value| %> <% end %> - + @@ -48,8 +48,8 @@ rows = 1 end %> <% @requested_n[index].each do |q, value| %> <% end %> diff --git a/app/views/ingredients/_options.html.erb b/app/views/foods/_options.html.erb similarity index 87% rename from app/views/ingredients/_options.html.erb rename to app/views/foods/_options.html.erb index 9b9708e..387a970 100644 --- a/app/views/ingredients/_options.html.erb +++ b/app/views/foods/_options.html.erb @@ -1,7 +1,7 @@
<%= l(:label_options) %>
- <%= form_tag toggle_column_project_ingredients_path(@project), + <%= form_tag toggle_column_project_foods_path(@project), id: 'toggle-column-form', name: 'toggle-column-form', method: :post, remote: true do %> diff --git a/app/views/foods/create.js.erb b/app/views/foods/create.js.erb new file mode 100644 index 0000000..98dd313 --- /dev/null +++ b/app/views/foods/create.js.erb @@ -0,0 +1,6 @@ +$('#new-food').empty(); +<% if params[:view] == 'index' %> + $('#foods').html('<%= j render partial: 'foods/index' %>'); +<% else %> + $('#nutrients').html('<%= j render partial: 'foods/nutrients' %>'); +<% end %> diff --git a/app/views/foods/destroy.js.erb b/app/views/foods/destroy.js.erb new file mode 100644 index 0000000..d1513c5 --- /dev/null +++ b/app/views/foods/destroy.js.erb @@ -0,0 +1,3 @@ +<% if @food.destroyed? %> + $('tr[id=food-<%= @food.id %>]').nextUntil('tr.primary').addBack().remove(); +<% end %> diff --git a/app/views/foods/edit.js.erb b/app/views/foods/edit.js.erb new file mode 100644 index 0000000..d9d1efe --- /dev/null +++ b/app/views/foods/edit.js.erb @@ -0,0 +1,8 @@ +$('tr[id=food-<%= @food.id %>]').nextUntil('tr.primary', ':not(.food)') + .remove(); +var columns = $('table > thead > tr > th').length; +$('tr[id=food-<%= @food.id %>]').nextUntil('tr.primary').addBack().last().after( + '
' +); diff --git a/app/views/foods/index.html.erb b/app/views/foods/index.html.erb new file mode 100644 index 0000000..94f72bd --- /dev/null +++ b/app/views/foods/index.html.erb @@ -0,0 +1,15 @@ +
+ <%= link_to t(".heading_nutrient_view"), nutrients_project_foods_path(@project), + class: 'icon icon-stats' %> + <%= render partial: 'foods/contextual', locals: {view: :index} %> +
+ +<%= render partial: 'foods/import' %> + +
+
+ +

<%= t ".heading" %>

+
+ <%= render partial: 'foods/index' %> +
diff --git a/app/views/foods/index.js.erb b/app/views/foods/index.js.erb new file mode 100644 index 0000000..65f6d75 --- /dev/null +++ b/app/views/foods/index.js.erb @@ -0,0 +1,5 @@ +<% if params[:view] == 'index' %> + $('#foods').html('<%= j render partial: 'foods/index' %>'); +<% else %> + $('#nutrients').html('<%= j render partial: 'foods/nutrients' %>'); +<% end %> diff --git a/app/views/foods/new.js.erb b/app/views/foods/new.js.erb new file mode 100644 index 0000000..db4618f --- /dev/null +++ b/app/views/foods/new.js.erb @@ -0,0 +1,2 @@ +$('#new-food') + .html('<%= j render partial: 'foods/new_form', locals: {view: params[:view]} %>'); diff --git a/app/views/foods/nutrients.html.erb b/app/views/foods/nutrients.html.erb new file mode 100644 index 0000000..fd1d212 --- /dev/null +++ b/app/views/foods/nutrients.html.erb @@ -0,0 +1,15 @@ +
+ <%= link_to t(".heading_food_list"), project_foods_path(@project), + class: 'icon icon-list' %> + <%= render partial: 'foods/contextual', locals: {view: :nutrients} %> +
+ +<%= render partial: 'foods/import' %> + +
+
+ +

<%= t ".heading" %>

+
+ <%= render partial: 'foods/nutrients' %> +
diff --git a/app/views/foods/toggle.js.erb b/app/views/foods/toggle.js.erb new file mode 100644 index 0000000..09d1456 --- /dev/null +++ b/app/views/foods/toggle.js.erb @@ -0,0 +1 @@ +$('#foods').html('<%= j render partial: 'foods/index' %>'); diff --git a/app/views/foods/toggle_column.js.erb b/app/views/foods/toggle_column.js.erb new file mode 100644 index 0000000..eb7fbec --- /dev/null +++ b/app/views/foods/toggle_column.js.erb @@ -0,0 +1 @@ +$('#nutrients').html('<%= j render partial: 'foods/nutrients' %>'); diff --git a/app/views/ingredients/_contextual.html.erb b/app/views/ingredients/_contextual.html.erb deleted file mode 100644 index e016cc9..0000000 --- a/app/views/ingredients/_contextual.html.erb +++ /dev/null @@ -1,6 +0,0 @@ -<% if User.current.allowed_to?(:manage_common, @project) %> - <%= link_to t(".link_import_ingredients"), '#', class: 'icon icon-multiple', - onclick: '$("#import-ingredients").show(); $("#filename").focus(); return false;' %> - <%= link_to t(".link_new_ingredient"), new_project_ingredient_path(@project, view: view), - {remote: true, class: 'icon icon-add'} %> -<% end %> diff --git a/app/views/ingredients/_new_form.html.erb b/app/views/ingredients/_new_form.html.erb deleted file mode 100644 index 83d5b62..0000000 --- a/app/views/ingredients/_new_form.html.erb +++ /dev/null @@ -1,18 +0,0 @@ -

<%= t ".heading_new_ingredient" %>

- -<%= labelled_form_for @ingredient, - url: project_ingredients_path(@project, view: view), - remote: true, - html: {id: 'new-ingredient-form', name: 'new-ingredient-form'} do |f| %> - - <%= render partial: 'ingredients/form', locals: {f: f} %> - -
-

- <%= submit_tag l(:button_create) %> - <%= link_to l(:button_cancel), "#", - onclick: '$("#new-ingredient").empty(); return false;' %> -

-
-<% end %> -
diff --git a/app/views/ingredients/create.js.erb b/app/views/ingredients/create.js.erb deleted file mode 100644 index 1194715..0000000 --- a/app/views/ingredients/create.js.erb +++ /dev/null @@ -1,6 +0,0 @@ -$('#new-ingredient').empty(); -<% if params[:view] == 'index' %> - $('#ingredients').html('<%= j render partial: 'ingredients/index' %>'); -<% else %> - $('#nutrients').html('<%= j render partial: 'ingredients/nutrients' %>'); -<% end %> diff --git a/app/views/ingredients/destroy.js.erb b/app/views/ingredients/destroy.js.erb deleted file mode 100644 index 691a0b5..0000000 --- a/app/views/ingredients/destroy.js.erb +++ /dev/null @@ -1,3 +0,0 @@ -<% if @ingredient.destroyed? %> - $('tr[id=ingredient-<%= @ingredient.id %>]').nextUntil('tr.primary').addBack().remove(); -<% end %> diff --git a/app/views/ingredients/edit.js.erb b/app/views/ingredients/edit.js.erb deleted file mode 100644 index 4e225a9..0000000 --- a/app/views/ingredients/edit.js.erb +++ /dev/null @@ -1,8 +0,0 @@ -$('tr[id=ingredient-<%= @ingredient.id %>]').nextUntil('tr.primary', ':not(.ingredient)') - .remove(); -var columns = $('table > thead > tr > th').length; -$('tr[id=ingredient-<%= @ingredient.id %>]').nextUntil('tr.primary').addBack().last().after( - '' -); diff --git a/app/views/ingredients/index.html.erb b/app/views/ingredients/index.html.erb deleted file mode 100644 index 4174433..0000000 --- a/app/views/ingredients/index.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -
- <%= link_to t(".heading_nutrient_view"), nutrients_project_ingredients_path(@project), - class: 'icon icon-stats' %> - <%= render partial: 'ingredients/contextual', locals: {view: :index} %> -
- -<%= render partial: 'ingredients/import' %> - -
-
- -

<%= t ".heading" %>

-
- <%= render partial: 'ingredients/index' %> -
diff --git a/app/views/ingredients/index.js.erb b/app/views/ingredients/index.js.erb deleted file mode 100644 index 0205e27..0000000 --- a/app/views/ingredients/index.js.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% if params[:view] == 'index' %> - $('#ingredients').html('<%= j render partial: 'ingredients/index' %>'); -<% else %> - $('#nutrients').html('<%= j render partial: 'ingredients/nutrients' %>'); -<% end %> diff --git a/app/views/ingredients/new.js.erb b/app/views/ingredients/new.js.erb deleted file mode 100644 index 7c7880c..0000000 --- a/app/views/ingredients/new.js.erb +++ /dev/null @@ -1,2 +0,0 @@ -$('#new-ingredient') - .html('<%= j render partial: 'ingredients/new_form', locals: {view: params[:view]} %>'); diff --git a/app/views/ingredients/nutrients.html.erb b/app/views/ingredients/nutrients.html.erb deleted file mode 100644 index de19983..0000000 --- a/app/views/ingredients/nutrients.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -
- <%= link_to t(".heading_ingredient_list"), project_ingredients_path(@project), - class: 'icon icon-list' %> - <%= render partial: 'ingredients/contextual', locals: {view: :nutrients} %> -
- -<%= render partial: 'ingredients/import' %> - -
-
- -

<%= t ".heading" %>

-
- <%= render partial: 'ingredients/nutrients' %> -
diff --git a/app/views/ingredients/toggle.js.erb b/app/views/ingredients/toggle.js.erb deleted file mode 100644 index 38570b4..0000000 --- a/app/views/ingredients/toggle.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('#ingredients').html('<%= j render partial: 'ingredients/index' %>'); diff --git a/app/views/ingredients/toggle_column.js.erb b/app/views/ingredients/toggle_column.js.erb deleted file mode 100644 index 543d759..0000000 --- a/app/views/ingredients/toggle_column.js.erb +++ /dev/null @@ -1 +0,0 @@ -$('#nutrients').html('<%= j render partial: 'ingredients/nutrients' %>'); diff --git a/app/views/layouts/_sidebar.html.erb b/app/views/layouts/_sidebar.html.erb index 214d2df..7ea4167 100644 --- a/app/views/layouts/_sidebar.html.erb +++ b/app/views/layouts/_sidebar.html.erb @@ -12,9 +12,9 @@
  • <%= link_to t(".link_meals"), project_meals_path(@project) %>
  • - <%= link_to t(".link_ingredients"), project_ingredients_path(@project) %> + <%= link_to t(".link_foods"), project_foods_path(@project) %> / - <%= link_to t(".link_nutrients"), nutrients_project_ingredients_path(@project) %> + <%= link_to t(".link_nutrients"), nutrients_project_foods_path(@project) %>
diff --git a/assets/stylesheets/body_tracking.css b/assets/stylesheets/body_tracking.css index f7d4a50..852f502 100644 --- a/assets/stylesheets/body_tracking.css +++ b/assets/stylesheets/body_tracking.css @@ -1,6 +1,6 @@ table.list tr.quantity.primary td.name {font-weight: bold;} -table.list tr.ingredient.hidden {opacity: 0.4} +table.list tr.food.hidden {opacity: 0.4} table.list .date, table.list .name, diff --git a/config/locales/en.yml b/config/locales/en.yml index 6eb040c..e7bfac3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -27,10 +27,10 @@ en: readouts: duplicated_quantity_unit_pair: 'you can define each quantity/unit pair only once per measurement' - ingredient: + food: attributes: nutrients: - duplicated_quantity: 'you can define each quantity only once per ingredient' + duplicated_quantity: 'you can define each nutrient quantity only once per food' quantity: attributes: parent: @@ -57,7 +57,7 @@ en: link_summary: 'Summary' link_meals: 'Meals' link_measurements: 'Measurements' - link_ingredients: 'Ingredients' + link_foods: 'Foods' link_nutrients: 'Nutrients' link_sources: 'Data sources' link_quantities: 'Quantities' @@ -79,18 +79,18 @@ en: heading_new_measurement: 'New measurement' index: heading: 'Measurements' - ingredients: + foods: contextual: - link_import_ingredients: 'Import' - link_new_ingredient: 'New ingredient' + link_import_foods: 'Import' + link_new_food: 'New food' filters: visibility_prompt: 'all' import: - heading_import_ingredients: 'Import' + heading_import_foods: 'Import' label_import_select_csv_file: 'Select CSV file' import_hints: 'CSV file has to include header with column names. Recognized column names are: - (1) ingredient attributes, case sensitive: + (1) food attributes, case sensitive: "Name" - required, "Notes" - optional, "Reference" - defaults to 100[g], "Group" - defaults to "other", "Source" - optional, "SourceIdent" - optional, (2) quantities'' names with unit short name in square brackets. @@ -105,13 +105,13 @@ en: other: 'other' meat: 'meat' new_form: - heading_new_ingredient: 'New ingredient' + heading_new_food: 'New food' index: - heading: 'Ingredients' + heading: 'Foods' heading_nutrient_view: 'Nutrient view' nutrients: heading: 'Nutrients' - heading_ingredient_list: 'Ingredient list' + heading_food_list: 'Food list' sources: index: heading: 'Data sources' diff --git a/config/routes.rb b/config/routes.rb index 5a255f5..26af335 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,7 +22,7 @@ resources :projects, shallow: true do get 'filter' end end - resources :ingredients, only: [:index, :new, :create, :edit, :update, :destroy] do + resources :foods, only: [:index, :new, :create, :edit, :update, :destroy] do post 'toggle', on: :member collection do get 'nutrients' diff --git a/db/migrate/001_create_schema.rb b/db/migrate/001_create_schema.rb index c10d077..b4bd8d9 100644 --- a/db/migrate/001_create_schema.rb +++ b/db/migrate/001_create_schema.rb @@ -39,7 +39,7 @@ class CreateSchema < ActiveRecord::Migration t.timestamps null: false end - create_table :ingredients do |t| + create_table :foods do |t| t.references :project t.string :name t.text :notes @@ -54,7 +54,7 @@ class CreateSchema < ActiveRecord::Migration end create_table :nutrients do |t| - t.references :ingredient + t.references :food t.references :quantity t.decimal :amount, precision: 12, scale: 6 t.references :unit @@ -91,9 +91,9 @@ class CreateSchema < ActiveRecord::Migration t.timestamps null: false end - create_table :compositions_ingredients do |t| + create_table :ingredients do |t| t.references :composition, polymorphic: true - t.references :ingredient + t.references :food t.references :part_of t.decimal :ready_ratio, precision: 12, scale: 6 t.decimal :amount, precision: 12, scale: 6 diff --git a/init.rb b/init.rb index 2c25d26..7ed1935 100644 --- a/init.rb +++ b/init.rb @@ -16,7 +16,7 @@ Redmine::Plugin.register :body_tracking do meals: [:index], measurement_routines: [:show], measurements: [:index, :readouts, :filter], - ingredients: [:index, :nutrients, :filter], + foods: [:index, :nutrients, :filter], sources: [:index], quantities: [:index, :parents, :filter], units: [:index], @@ -26,7 +26,7 @@ Redmine::Plugin.register :body_tracking do meals: [:new, :create, :edit, :update, :destroy], measurement_routines: [:edit], measurements: [:new, :create, :edit, :update, :destroy, :retake, :toggle_column], - ingredients: [:new, :create, :edit, :update, :destroy, :toggle, :toggle_column, + foods: [:new, :create, :edit, :update, :destroy, :toggle, :toggle_column, :import], sources: [:create, :destroy], quantities: [:new, :create, :edit, :update, :destroy, :move, :new_child, :create_child], diff --git a/lib/body_tracking/items_with_quantities.rb b/lib/body_tracking/items_with_quantities.rb index 337e451..9d5c65f 100644 --- a/lib/body_tracking/items_with_quantities.rb +++ b/lib/body_tracking/items_with_quantities.rb @@ -1,10 +1,10 @@ module BodyTracking module ItemsWithQuantities RELATIONS = { - 'Ingredient' => { + 'Food' => { domain: :diet, subitem_class: Nutrient, - foreign_key: :ingredient_id, + foreign_key: :food_id, value_field: :amount }, 'Measurement' => { diff --git a/lib/body_tracking/project_patch.rb b/lib/body_tracking/project_patch.rb index 0bc75c7..3db3811 100644 --- a/lib/body_tracking/project_patch.rb +++ b/lib/body_tracking/project_patch.rb @@ -5,7 +5,7 @@ module BodyTracking::ProjectPatch has_many :measurement_routines, dependent: :destroy has_many :measurements, -> { order "taken_at DESC" }, dependent: :destroy, extend: BodyTracking::ItemsWithQuantities, through: :measurement_routines - has_many :ingredients, -> { order "name" }, dependent: :destroy, + has_many :foods, -> { order "name" }, dependent: :destroy, extend: BodyTracking::ItemsWithQuantities has_many :sources, dependent: :destroy diff --git a/test/functional/ingredients_controller_test.rb b/test/functional/foods_controller_test.rb similarity index 69% rename from test/functional/ingredients_controller_test.rb rename to test/functional/foods_controller_test.rb index abd52e2..de5faa0 100644 --- a/test/functional/ingredients_controller_test.rb +++ b/test/functional/foods_controller_test.rb @@ -1,6 +1,6 @@ require File.expand_path('../../test_helper', __FILE__) -class IngredientsControllerTest < ActionController::TestCase +class FoodsControllerTest < ActionController::TestCase # Replace this with your real tests. def test_truth assert true diff --git a/test/unit/ingredient_test.rb b/test/unit/food_test.rb similarity index 74% rename from test/unit/ingredient_test.rb rename to test/unit/food_test.rb index 92597c2..5a809c3 100644 --- a/test/unit/ingredient_test.rb +++ b/test/unit/food_test.rb @@ -1,6 +1,6 @@ require File.expand_path('../../test_helper', __FILE__) -class IngredientTest < ActiveSupport::TestCase +class FoodTest < ActiveSupport::TestCase # Replace this with your real tests. def test_truth
- <%= link_to '', toggle_ingredient_path(i), { + <%= link_to '', toggle_food_path(f), { remote: true, method: :post, class: "icon icon-eye" } %> - <%= i.name %> + <%= f.name %> <%= i.notes %><%= i.ref_amount %> [<%= i.ref_unit.shortname %>]<%= i.group %><%= f.notes %><%= f.ref_amount %> [<%= f.ref_unit.shortname %>]<%= f.group %> - <%= i.source.name if i.source.present? %> - <%= ", #{i.source_ident}" if i.source_ident.present? %> + <%= f.source.name if f.source.present? %> + <%= ", #{f.source_ident}" if f.source_ident.present? %> <%= action_links(i, :index) %><%= action_links(f, :index) %>
<%= link_to '', - toggle_column_project_ingredients_path(@project, quantity_id: q.id), + toggle_column_project_foods_path(@project, quantity_id: q.id), {class: "icon icon-close", method: :post, remote: true} %>
<%= q.name %> @@ -28,17 +28,17 @@
- <%= i.name %> + onclick="$(this).closest('tr').toggle(); $(this).closest('tr').nextUntil('tr.primary', '.food').toggle(); return false;"> + <%= f.name %> <%= format_value(value) %><%= action_links(i, :nutrients) %><%= action_links(f, :nutrients) %>
' + + '<%= j render partial: 'foods/edit_form', locals: {view: params[:view]} %>' + + '
' + - '<%= j render partial: 'ingredients/edit_form', locals: {view: params[:view]} %>' + - '