1
0

Filtering ingredients by formula working

This commit is contained in:
cryptogopher
2019-11-08 23:42:41 +01:00
parent 4ab24aa223
commit 70b6e97b87
4 changed files with 51 additions and 40 deletions

View File

@@ -196,48 +196,29 @@ class IngredientsController < ApplicationController
end
def prepare_ingredients
@ingredients = filter_ingredients.includes(:ref_unit, :source)
@ingredients = @project.ingredients.includes(:ref_unit, :source)
.filter(@project, session[:filters])
end
def prepare_nutrients
@quantities = @project.quantities.where(primary: true)
nutrients = filter_ingredients.compute_nutrients(@quantities)
ingredients, requested_n, extra_n = @project.ingredients
.filter(@project, session[:filters], @quantities)
@nutrients = {}
@extra_nutrients = {}
nutrients.each do |i, requested_n, extra_n|
ingredients.each_with_index do |i, index|
@nutrients[i] = []
requested_n.each do |q_name, value|
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.each do |q_name, value|
extra_n[index].each do |q_name, value|
amount, unitname = value
@extra_nutrients[i] << [q_name, amount.nil? ? '-' : "#{amount} [#{unitname || '-'}]"]
end
end
end
def filter_ingredients
filters = session[:filters] || {}
ingredients = @project.ingredients
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
if filters[:nutrients].present?
formula = Formula.new(self.project, filters[:nutrients], comparison: true)
if formula.valid?
end
end
ingredients
end
end

View File

@@ -1,4 +1,6 @@
class Ingredient < ActiveRecord::Base
include BodyTracking::Formula
enum group: {
other: 0,
meat: 1
@@ -35,9 +37,36 @@ class Ingredient < ActiveRecord::Base
end
end
def self.compute_nutrients(requested_q)
def self.filter(project, filters = {}, requested_q = [])
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?
formula = Formula.new(project, filters[:nutrients])
if formula.valid?
project.quantities.new(name: '__internal_q', formula: filters[:nutrients])
end
end
if !requested_q.empty? || formula_q.present?
result = self.compute_nutrients(requested_q, formula_q)
requested_q.present? ? result : result[0]
else
ingredients
end
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)
@@ -90,10 +119,12 @@ class Ingredient < ActiveRecord::Base
end
all_q = nutrients.merge(completed_q)
ingredients.map do |i|
requested_n = requested_q.map { |q| [q.name, all_q[q.name][i.id]] }
extra_n = extra_q.map { |q_name| [q_name, all_q[q_name][i.id]] if all_q[q_name][i.id] }
[i, requested_n, extra_n.compact]
end
[
filter_q ? ingredients.to_a.keep_if { |i| all_q[filter_q.name][i.id] } : 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

View File

@@ -15,7 +15,7 @@
<td style="width:100%;">
<%= text_field_tag 'filters[nutrients]', session[:filters][:nutrients],
placeholder: 'conditional expression including nutrients', size: 40,
style: "box-sizing:border-box; width:100%;",
:style => 'box-sizing:border-box; width:100%;',
:onblur => '$("#filters_form").submit(); return false;' %>
</td>
<td>