diff --git a/app/controllers/ingredients_controller.rb b/app/controllers/ingredients_controller.rb index 642b39b..6cdd56d 100644 --- a/app/controllers/ingredients_controller.rb +++ b/app/controllers/ingredients_controller.rb @@ -3,6 +3,8 @@ class IngredientsController < ApplicationController menu_item :body_trackers + helper :body_trackers + before_action :init_session_filters before_action :find_project_by_project_id, only: [:index, :nutrients, :create, :import, :filter, :filter_nutrients] @@ -204,29 +206,14 @@ class IngredientsController < ApplicationController end def prepare_ingredients - @ingredients, @formula_q = @project.ingredients.includes(:ref_unit, :source) - .filter(@project, session[:i_filters]) + @ingredients, @formula_q = @project.ingredients + .includes(:ref_unit, :source) + .filter(session[:i_filters]) end def prepare_nutrients @quantities = @project.nutrients_column_view.quantities - ingredients, requested_n, extra_n, @formula_q = @project.ingredients - .filter(@project, session[:i_filters], @quantities) - - @nutrients = {} - @extra_nutrients = {} - ingredients.each_with_index do |i, index| - @nutrients[i] = [] - requested_n[index].each do |q_name, value| - amount, unitname = value - @nutrients[i] << [q_name, amount.nil? ? '-' : "#{amount} [#{unitname || '-'}]"] - end - - @extra_nutrients[i] = [] - extra_n[index].each do |q_name, value| - amount, unitname = value - @extra_nutrients[i] << [q_name, amount.nil? ? '-' : "#{amount} [#{unitname || '-'}]"] - end - end + @ingredients, @requested_n, @extra_n, @formula_q = @project.ingredients + .filter(session[:i_filters], @quantities) end end diff --git a/app/controllers/measurements_controller.rb b/app/controllers/measurements_controller.rb index eb00545..9de8107 100644 --- a/app/controllers/measurements_controller.rb +++ b/app/controllers/measurements_controller.rb @@ -1,6 +1,8 @@ class MeasurementsController < ApplicationController menu_item :body_trackers + helper :body_trackers + before_action :init_session_filters before_action :find_project_by_project_id, only: [:index, :new, :create, :filter] before_action :find_quantity_by_quantity_id, only: [:toggle_column] diff --git a/app/helpers/body_trackers_helper.rb b/app/helpers/body_trackers_helper.rb index 39a5f1c..ef34b8a 100644 --- a/app/helpers/body_trackers_helper.rb +++ b/app/helpers/body_trackers_helper.rb @@ -1,2 +1,6 @@ module BodyTrackersHelper + def format_value(value) + amount, unitname = value + amount.nil? ? '-' : "#{amount} [#{unitname || '-'}]" + end end diff --git a/app/helpers/ingredients_helper.rb b/app/helpers/ingredients_helper.rb index 53eaf9b..3c9a476 100644 --- a/app/helpers/ingredients_helper.rb +++ b/app/helpers/ingredients_helper.rb @@ -38,4 +38,8 @@ module IngredientsHelper [translations[k.to_sym], k] end end + + def action_links(i) + delete_link(ingredient_path(i), {remote: true, data: {}}) + end end diff --git a/app/helpers/measurements_helper.rb b/app/helpers/measurements_helper.rb index 484b873..5dc740d 100644 --- a/app/helpers/measurements_helper.rb +++ b/app/helpers/measurements_helper.rb @@ -9,11 +9,6 @@ module MeasurementsHelper m.taken_at.getlocal.strftime("%R") end - def format_value(value) - amount, unitname = value - amount.nil? ? '-' : "#{amount} [#{unitname || '-'}]" - end - def toggle_column_options disabled = [] enabled_columns = @scoping_measurement.column_view.quantities diff --git a/app/models/ingredient.rb b/app/models/ingredient.rb index 0e90b92..88749ec 100644 --- a/app/models/ingredient.rb +++ b/app/models/ingredient.rb @@ -1,6 +1,4 @@ class Ingredient < ActiveRecord::Base - include BodyTracking::Formula - enum group: { other: 0, meat: 1 @@ -23,7 +21,8 @@ class Ingredient < ActiveRecord::Base } # Nutrient quantity_id uniqueness check for nested attributes validate do - quantities = self.nutrients.map { |n| n.quantity_id } + quantities = self.nutrients.reject { |n| n.marked_for_destruction? } + .map { |n| n.quantity_id } if quantities.length != quantities.uniq.length errors.add(:nutrients, :duplicated_quantity) end @@ -46,95 +45,4 @@ class Ingredient < ActiveRecord::Base def toggle_hidden! self.toggle!(:hidden) end - - def self.filter(project, filters, requested_q = Quantity.none) - ingredients = all - - if filters[:name].present? - ingredients = ingredients.where("name LIKE ?", "%#{filters[:name]}%") - end - - if filters[:visibility].present? - ingredients = ingredients.where(hidden: filters[:visibility] == "1" ? false : true) - end - - formula_q = if filters[:nutrients].present? - project.quantities.new(name: '__internal_q', - formula: filters[:nutrients], - domain: :diet) - end - apply_formula = formula_q.present? && formula_q.valid? - - result = - if !requested_q.empty? || apply_formula - computed = ingredients.compute_nutrients(requested_q, apply_formula && formula_q) - requested_q.present? ? computed : [computed[0]] - else - [ingredients] - end - result.push(formula_q) - end - - def self.compute_nutrients(requested_q, filter_q = nil) - ingredients = all - unchecked_q = requested_q.map { |q| [q, nil] } - unchecked_q << [filter_q, nil] if filter_q - - nutrients = Hash.new { |h,k| h[k] = {} } - Nutrient.where(ingredient: ingredients).includes(:quantity, :unit) - .order('quantities.lft') - .pluck('quantities.name', :ingredient_id, :amount, 'units.shortname') - .each { |q_name, i_id, a, u_id| nutrients[q_name][i_id] = [a, u_id] } - - extra_q = nutrients.keys - requested_q.pluck(:name) - - completed_q = {} - # FIXME: loop should finish unless there is circular dependency in formulas - # for now we don't guard against that - while !unchecked_q.empty? - q, deps = unchecked_q.shift - - # quantity not computable (no formula) or not requiring calculation/computed - if q.formula.blank? || (nutrients[q.name].length == ingredients.count) - completed_q[q.name] = nutrients.delete(q.name) { {} } - next - end - - # quantity with formula requires refresh of dependencies availability - if deps.nil? || !deps.empty? - deps ||= q.formula_quantities - deps.reject! { |q| completed_q.has_key?(q.name) } - deps.each { |q| unchecked_q << [q, nil] unless unchecked_q.index { |u| u[0] == q } } - end - - # quantity with formula has all dependencies satisfied, requires calculation - if deps.empty? - input_q = q.formula_quantities - inputs = ingredients.select { |i| nutrients[q.name][i.id].nil? }.map do |i| - [ - i, - input_q.map do |i_q| - nutrient_data = completed_q[i_q.name][i.id] || [nil, nil] - [i_q.name, nutrient_data[0]] - end.to_h - ] - end - q.calculate(inputs).each { |i, result| nutrients[q.name][i.id] = result } - unchecked_q.unshift([q, deps]) - next - end - - # quantity still has unsatisfied dependencies, move to the end of queue - unchecked_q << [q, deps] - end - - all_q = nutrients.merge(completed_q) - [ - filter_q ? ingredients.to_a.keep_if { |i| all_q[filter_q.name][i.id][0] } : ingredients, - ingredients.map { |i| requested_q.map { |q| [q.name, all_q[q.name][i.id]] } }, - ingredients.map do |i| - extra_q.map { |q_name| [q_name, all_q[q_name][i.id]] if all_q[q_name][i.id] } - end - ] - end end diff --git a/app/models/measurement.rb b/app/models/measurement.rb index ff92746..800b14b 100644 --- a/app/models/measurement.rb +++ b/app/models/measurement.rb @@ -10,9 +10,8 @@ class Measurement < ActiveRecord::Base # Readout quantity_id + unit_id uniqueness validation. Cannot be effectively # checked on Readout model level. validate do - quantities = self.readouts.map do |r| - [r.quantity_id, r.unit_id] unless r.marked_for_destruction? - end + quantities = self.readouts.reject { |r| r.marked_for_destruction? } + .map { |r| [r.quantity_id, r.unit_id] } if quantities.length != quantities.uniq.length errors.add(:readouts, :duplicated_quantity_unit_pair) end diff --git a/app/views/ingredients/_filters.html.erb b/app/views/ingredients/_filters.html.erb index bcc4d21..7f7be6a 100644 --- a/app/views/ingredients/_filters.html.erb +++ b/app/views/ingredients/_filters.html.erb @@ -19,7 +19,7 @@ onchange: '$("#filters-form").submit();' %>
<%= l(:field_name) %> | - <% @quantities.each do |q| %> -<%= q.name %> | - <% end %> -
---|---|
- <%= i.name %> - | - <% values.each do |*, value| %> -<%= value %> | - <% end %> -
<%= l(:label_no_data) %>
-<% end %> diff --git a/app/views/ingredients/_nutrients.html.erb b/app/views/ingredients/_nutrients.html.erb new file mode 100644 index 0000000..3c801d5 --- /dev/null +++ b/app/views/ingredients/_nutrients.html.erb @@ -0,0 +1,79 @@ +<%= render partial: 'ingredients/filters', + locals: {url: filter_nutrients_project_ingredients_path(@project)} %> + +<% if @ingredients.any? %> + <%= render partial: 'ingredients/options' %> + +<%= l(:field_name) %> | + <% @quantities.each do |q| %> +
+
+ <%= link_to '',
+ toggle_column_project_ingredients_path(@project, quantity_id: q.id),
+ {class: "icon icon-close", method: :post, remote: true} %>
+
+ <%= q.name %>
+ |
+ <% end %>
+ <%= l(:field_action) %> | +
---|---|---|
+ <%= i.name %> + | + <% @requested_n[index].each do |*, value| %> +<%= format_value(value) %> | + <% end %> +<%= action_links(i) %> | +
<%= l(:label_no_data) %>
+<% end %> diff --git a/app/views/ingredients/_options.html.erb b/app/views/ingredients/_options.html.erb index 5c1475f..9b9708e 100644 --- a/app/views/ingredients/_options.html.erb +++ b/app/views/ingredients/_options.html.erb @@ -8,28 +8,10 @@- | - <%= select_tag 'quantity_id', toggle_column_options %> - | -- <%= submit_tag l(:button_add) %> - | +<%= select_tag 'quantity_id', toggle_column_options %> | +<%= submit_tag l(:button_add) %> |
- <%= link_to l(:button_hide), - toggle_column_project_ingredients_path(@project, quantity_id: q.id), - {class: "icon icon-close", method: :post, remote: true} %> - | - <% end %> -