1
0

Fix migration of default quantities

Allow Quantity formula to be nil but not blank
Add computed energy quantity
Reverse default quantities deletion order
This commit is contained in:
cryptogopher 2019-11-15 00:04:34 +01:00
parent 0e5a53b4b9
commit 3ce5d5c940
4 changed files with 134 additions and 125 deletions

View File

@ -59,6 +59,7 @@ class QuantitiesController < ApplicationController
private private
def quantity_params def quantity_params
params[:quantity].delete(:formula) if params[:quantity][:formula].blank?
params.require(:quantity).permit( params.require(:quantity).permit(
:domain, :domain,
:parent_id, :parent_id,

View File

@ -15,7 +15,7 @@ class Quantity < ActiveRecord::Base
validate if: -> { parent.present? } do validate if: -> { parent.present? } do
errors.add(:parent, :parent_domain_mismatch) unless domain == parent.domain errors.add(:parent, :parent_domain_mismatch) unless domain == parent.domain
end end
validates :formula, formula: true validates :formula, formula: {allow_nil: true}
after_initialize do after_initialize do
if new_record? if new_record?

View File

@ -1,133 +1,141 @@
class LoadDefaults < ActiveRecord::Migration class LoadDefaults < ActiveRecord::Migration
reversible do |dir| def change
dir.up do reversible do |dir|
Unit.create project: nil, shortname: "g", name: "gram" dir.up do
Unit.create project: nil, shortname: "mg", name: "milligram" Unit.create project: nil, shortname: "g", name: "gram"
Unit.create project: nil, shortname: "ug", name: "microgram" Unit.create project: nil, shortname: "mg", name: "milligram"
Unit.create project: nil, shortname: "kg", name: "kilogram" Unit.create project: nil, shortname: "ug", name: "microgram"
Unit.create project: nil, shortname: "kcal", name: "kilocalorie" Unit.create project: nil, shortname: "kg", name: "kilogram"
Unit.create project: nil, shortname: "%", name: "percent" Unit.create project: nil, shortname: "kcal", name: "kilocalorie"
Unit.create project: nil, shortname: "%", name: "percent"
# https://www.fsai.ie/uploadedFiles/Consol_Reg1169_2011.pdf # https://www.fsai.ie/uploadedFiles/Consol_Reg1169_2011.pdf
# https://www.fsai.ie/legislation/food_legislation/food_information_fic/nutrition_labelling.html # https://www.fsai.ie/legislation/food_legislation/food_information_fic/nutrition_labelling.html
e = Quantity.create project: nil, domain: :diet, parent: nil, name: "Energy", e = Quantity.create project: nil, domain: :diet, parent: nil, name: "Energy",
description: "Total energy", primary: true description: "Total energy", primary: true
Quantity.create project: nil, domain: :diet, parent: nil, name: "Proteins", p = Quantity.create project: nil, domain: :diet, parent: nil, name: "Proteins",
description: "Total amount of proteins", primary: true description: "Total amount of proteins", primary: true
f = Quantity.create project: nil, domain: :diet, parent: nil, name: "Fats", f = Quantity.create project: nil, domain: :diet, parent: nil, name: "Fats",
description: "Total lipids, including phospholipids", primary: true description: "Total lipids, including phospholipids", primary: true
f1 = Quantity.create project: nil, domain: :diet, parent: f, name: "Fatty acids", f1 = Quantity.create project: nil, domain: :diet, parent: f, name: "Fatty acids",
description: "" description: ""
f2 = Quantity.create project: nil, domain: :diet, parent: f1, name: "Saturated", f2 = Quantity.create project: nil, domain: :diet, parent: f1, name: "Saturated",
description: "Fatty acids without double bond" description: "Fatty acids without double bond"
f3 = Quantity.create project: nil, domain: :diet, parent: f1, name: "Unsaturated", f3 = Quantity.create project: nil, domain: :diet, parent: f1, name: "Unsaturated",
description: "" description: ""
f4 = Quantity.create project: nil, domain: :diet, parent: f3, name: "Monounsaturated", f4 = Quantity.create project: nil, domain: :diet, parent: f3, name: "Monounsaturated",
description: "Fatty acids with one cis double bond" description: "Fatty acids with one cis double bond"
f5 = Quantity.create project: nil, domain: :diet, parent: f3, name: "Polyunsaturated", f5 = Quantity.create project: nil, domain: :diet, parent: f3, name: "Polyunsaturated",
description: "Fatty acids with two or more cis, cis-methylene interrupted" \ description: "Fatty acids with two or more cis, cis-methylene interrupted" \
" double bonds; PUFA" " double bonds; PUFA"
f6 = Quantity.create project: nil, domain: :diet, parent: f3, name: "Trans", f6 = Quantity.create project: nil, domain: :diet, parent: f3, name: "Trans",
description: "Fatty acids with at least one non-conjugated C-C double bond in the" \ description: "Fatty acids with at least one non-conjugated C-C double bond in the" \
" trans configuration" " trans configuration"
f7 = Quantity.create project: nil, domain: :diet, parent: f5, name: "Omega-3 (n-3)", f7 = Quantity.create project: nil, domain: :diet, parent: f5, name: "Omega-3 (n-3)",
description: "" description: ""
f8 = Quantity.create project: nil, domain: :diet, parent: f5, name: "Omega-6 (n-6)", f8 = Quantity.create project: nil, domain: :diet, parent: f5, name: "Omega-6 (n-6)",
description: "" description: ""
f9 = Quantity.create project: nil, domain: :diet, parent: f7, name: "ALA 18:3(n-3)", f9 = Quantity.create project: nil, domain: :diet, parent: f7, name: "ALA 18:3(n-3)",
description: "alpha-Linolenic acid" description: "alpha-Linolenic acid"
f10 = Quantity.create project: nil, domain: :diet, parent: f7, name: "EPA 20:5(n-3)", f10 = Quantity.create project: nil, domain: :diet, parent: f7, name: "EPA 20:5(n-3)",
description: "Eicosapentaenoic acid; also icosapentaenoic acid" description: "Eicosapentaenoic acid; also icosapentaenoic acid"
f11 = Quantity.create project: nil, domain: :diet, parent: f7, name: "DHA 22:6(n-3)", f11 = Quantity.create project: nil, domain: :diet, parent: f7, name: "DHA 22:6(n-3)",
description: "Docosahexaenoic acid" description: "Docosahexaenoic acid"
c1 = Quantity.create project: nil, domain: :diet, parent: nil, name: "Carbohydrates", c1 = Quantity.create project: nil, domain: :diet, parent: nil, name: "Carbohydrates",
description: "Total amount of carbohydrates", primary: true description: "Total amount of carbohydrates", primary: true
c2 = Quantity.create project: nil, domain: :diet, parent: c1, name: "Digestible", c2 = Quantity.create project: nil, domain: :diet, parent: c1, name: "Digestible",
description: "" description: ""
c3 = Quantity.create project: nil, domain: :diet, parent: c2, name: "Sugars", c3 = Quantity.create project: nil, domain: :diet, parent: c2, name: "Sugars",
description: "Monosaccharides and disaccharides, excluding polyols" description: "Monosaccharides and disaccharides, excluding polyols"
c4 = Quantity.create project: nil, domain: :diet, parent: c3, name: "Monosaccharides", c4 = Quantity.create project: nil, domain: :diet, parent: c3, name: "Monosaccharides",
description: "" description: ""
c5 = Quantity.create project: nil, domain: :diet, parent: c4, name: "Glucose", c5 = Quantity.create project: nil, domain: :diet, parent: c4, name: "Glucose",
description: "" description: ""
c6 = Quantity.create project: nil, domain: :diet, parent: c4, name: "Fructose", c6 = Quantity.create project: nil, domain: :diet, parent: c4, name: "Fructose",
description: "" description: ""
c7 = Quantity.create project: nil, domain: :diet, parent: c3, name: "Disaccharides", c7 = Quantity.create project: nil, domain: :diet, parent: c3, name: "Disaccharides",
description: "" description: ""
c8 = Quantity.create project: nil, domain: :diet, parent: c7, name: "Sucrose", c8 = Quantity.create project: nil, domain: :diet, parent: c7, name: "Sucrose",
description: "" description: ""
c9 = Quantity.create project: nil, domain: :diet, parent: c7, name: "Lactose", c9 = Quantity.create project: nil, domain: :diet, parent: c7, name: "Lactose",
description: "" description: ""
c10 = Quantity.create project: nil, domain: :diet, parent: c2, name: "Polyols", c10 = Quantity.create project: nil, domain: :diet, parent: c2, name: "Polyols",
description: "Alcohols containing more than 2 hydroxyl groups" description: "Alcohols containing more than 2 hydroxyl groups"
c11 = Quantity.create project: nil, domain: :diet, parent: c2, c11 = Quantity.create project: nil, domain: :diet, parent: c2,
name: "Polysaccharides", description: "" name: "Polysaccharides", description: ""
c12 = Quantity.create project: nil, domain: :diet, parent: c11, name: "Starch", c12 = Quantity.create project: nil, domain: :diet, parent: c11, name: "Starch",
description: "" description: ""
c13 = Quantity.create project: nil, domain: :diet, parent: c1, name: "Indigestible", c13 = Quantity.create project: nil, domain: :diet, parent: c1, name: "Indigestible",
description: "" description: ""
c14 = Quantity.create project: nil, domain: :diet, parent: c13, name: "Fibre", c14 = Quantity.create project: nil, domain: :diet, parent: c13, name: "Fibre",
description: "Carbohydrate polymers with 3 or more monomeric units, which are" \ description: "Carbohydrate polymers with 3 or more monomeric units, which are" \
" neither digested nor absorbed in the human small intestine" " neither digested nor absorbed in the human small intestine"
m1 = Quantity.create project: nil, domain: :diet, parent: nil, name: "Minerals", m1 = Quantity.create project: nil, domain: :diet, parent: nil, name: "Minerals",
description: "" description: ""
m2 = Quantity.create project: nil, domain: :diet, parent: m1, name: "Salt", m2 = Quantity.create project: nil, domain: :diet, parent: m1, name: "Salt",
description: "Sodium chloride" description: "Sodium chloride"
v1 = Quantity.create project: nil, domain: :diet, parent: nil, name: "Vitamins", v1 = Quantity.create project: nil, domain: :diet, parent: nil, name: "Vitamins",
description: "" description: ""
v2 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin A", v2 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin A",
description: "" description: ""
v3 = Quantity.create project: nil, domain: :diet, parent: v2, name: "Retinol (A1)", v3 = Quantity.create project: nil, domain: :diet, parent: v2, name: "Retinol (A1)",
description: "" description: ""
v4 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Provitamin A", v4 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Provitamin A",
description: "" description: ""
v5 = Quantity.create project: nil, domain: :diet, parent: v4, name: "beta-Carotene", v5 = Quantity.create project: nil, domain: :diet, parent: v4, name: "beta-Carotene",
description: "" description: ""
v6 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin B", v6 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin B",
description: "" description: ""
v7 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Thiamine (B1)", v7 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Thiamine (B1)",
description: "" description: ""
v8 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Riboflavin (B2)", v8 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Riboflavin (B2)",
description: "Vitamin G" description: "Vitamin G"
v9 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Vitamin B3", v9 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Vitamin B3",
description: "Vitamin PP" description: "Vitamin PP"
v10 = Quantity.create project: nil, domain: :diet, parent: v9, name: "Niacin", v10 = Quantity.create project: nil, domain: :diet, parent: v9, name: "Niacin",
description: "Nicotinic acid" description: "Nicotinic acid"
v11 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Vitamin B5", v11 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Vitamin B5",
description: "Pantothenic acid" description: "Pantothenic acid"
v12 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Vitamin B6", v12 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Vitamin B6",
description: "" description: ""
v13 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Biotin (B7)", v13 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Biotin (B7)",
description: "Vitamin H, also coenzyme R" description: "Vitamin H, also coenzyme R"
v14 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Folate", v14 = Quantity.create project: nil, domain: :diet, parent: v6, name: "Folate",
description: "Includes: folic acid, folacin and vitamin B9" description: "Includes: folic acid, folacin and vitamin B9"
v15 = Quantity.create project: nil, domain: :diet, parent: v14, name: "Vitamin B9", v15 = Quantity.create project: nil, domain: :diet, parent: v14, name: "Vitamin B9",
description: "" description: ""
v16 = Quantity.create project: nil, domain: :diet, parent: v6, v16 = Quantity.create project: nil, domain: :diet, parent: v6,
name: "Cobalamin (B12)", description: "" name: "Cobalamin (B12)", description: ""
v17 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin C", v17 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin C",
description: "" description: ""
v18 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin D", v18 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin D",
description: "Calciferol" description: "Calciferol"
v19 = Quantity.create project: nil, domain: :diet, parent: v18, v19 = Quantity.create project: nil, domain: :diet, parent: v18,
name: "Cholecalciferol (D3)", description: "" name: "Cholecalciferol (D3)", description: ""
v20 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin E", v20 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin E",
description: "" description: ""
v21 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin K", v21 = Quantity.create project: nil, domain: :diet, parent: v1, name: "Vitamin K",
description: "" description: ""
Source.create project: nil, name: "nutrition label", # Calculated quantities go at the and to make sure dependencies exist
description: "nutrition facts taken from package nutrition label" e1 = Quantity.create project: nil, domain: :diet, parent: e, name: "Calculated",
end description: "Total energy calculated from macronutrients", primary: true,
dir.down do formula: "4*Proteins + 9*Fats + 4*Carbohydrates"
Unit.where(project: nil).delete_all
Quantity.where(project: nil).delete_all Source.create project: nil, name: "nutrition label",
Source.where(project: nil).delete_all description: "nutrition facts taken from package nutrition label"
end
dir.down do
Source.where(project: nil).delete_all
Quantity.where(project: nil).delete_all
Unit.where(project: nil).delete_all
end
end end
end end
end end

View File

@ -7,7 +7,7 @@ module BodyTracking
class InvalidFormula < RuntimeError; end class InvalidFormula < RuntimeError; end
class Formula class Formula
def initialize(project, formula) def initialize(project, formula)
@project = project @project_quantities = Quantity.where(project: project)
@formula = formula @formula = formula
@paramed_formula = nil @paramed_formula = nil
@quantities = nil @quantities = nil
@ -79,7 +79,7 @@ module BodyTracking
# 4th: check if identifiers used in formula correspond to existing quantities # 4th: check if identifiers used in formula correspond to existing quantities
identifiers.uniq! identifiers.uniq!
quantities = @project.quantities.where(name: identifiers) quantities = @project_quantities.where(name: identifiers)
quantities_names = quantities.pluck(:name) quantities_names = quantities.pluck(:name)
(identifiers - quantities_names).each do |q| (identifiers - quantities_names).each do |q|
errors << [:unknown_quantity, {quantity: q}] errors << [:unknown_quantity, {quantity: q}]