120 lines
2.9 KiB
Ruby
120 lines
2.9 KiB
Ruby
class MealsController < ApplicationController
|
|
layout 'body_tracking'
|
|
menu_item :body_trackers
|
|
helper :body_trackers
|
|
|
|
include Concerns::Finders
|
|
|
|
before_action :find_project_by_project_id, only: [:index, :new, :create]
|
|
before_action :find_quantity_by_quantity_id, only: [:toggle_exposure]
|
|
before_action :find_meal, only: [:edit, :update, :destroy, :edit_notes, :update_notes,
|
|
:toggle_eaten]
|
|
before_action :authorize
|
|
|
|
def index
|
|
prepare_meals
|
|
end
|
|
|
|
def new
|
|
@meal = @project.meals.new
|
|
@meal.ingredients.new
|
|
end
|
|
|
|
def create
|
|
@meal = @project.meals.new(meal_params)
|
|
if @meal.save
|
|
flash[:notice] = 'Created new meal'
|
|
prepare_meals
|
|
else
|
|
@meal.ingredients.new if @meal.ingredients.empty?
|
|
render :new
|
|
end
|
|
end
|
|
|
|
def edit
|
|
end
|
|
|
|
def update
|
|
if @meal.update(meal_params)
|
|
flash[:notice] = 'Updated meal'
|
|
prepare_meals
|
|
render :index
|
|
else
|
|
render :edit
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
flash[:notice] = 'Deleted meal' if @meal.destroy
|
|
end
|
|
|
|
def edit_notes
|
|
end
|
|
|
|
def update_notes
|
|
@meal.update(params.require(:meal).permit(:notes))
|
|
end
|
|
|
|
def toggle_eaten
|
|
@meal.toggle_eaten!
|
|
prepare_meals
|
|
end
|
|
|
|
def toggle_exposure
|
|
@project.meal_exposures.toggle!(@quantity)
|
|
prepare_meals
|
|
end
|
|
|
|
private
|
|
|
|
def meal_params
|
|
params.require(:meal).permit(
|
|
:notes,
|
|
ingredients_attributes:
|
|
[
|
|
:id,
|
|
:food_id,
|
|
:amount,
|
|
:_destroy
|
|
]
|
|
)
|
|
end
|
|
|
|
def prepare_meals
|
|
@quantities = @project.meal_quantities.includes(:formula)
|
|
foods = @project.meal_foods.compute_quantities(@quantities)
|
|
ingredients = @project.meal_ingredients
|
|
|
|
@amount_mfu_unit = ingredients
|
|
.each_with_object(Hash.new(0)) { |i, h| h[i.food.ref_unit] += 1 }
|
|
.max_by(&:last).try(&:first)
|
|
|
|
@nutrients = {}
|
|
@nutrient_summary = Hash.new { |h,k| h[k] = Hash.new(BigDecimal(0)) }
|
|
@quantities.each do |q|
|
|
@nutrients[q] = ingredients.find_all { |i| foods[i.food][q] }.map do |i|
|
|
n_amount, n_unit = foods[i.food][q]
|
|
[i, [n_amount * i.amount / i.food.ref_amount, n_unit]]
|
|
end.to_h
|
|
|
|
mfu_unit = @nutrients[q].each_with_object(Hash.new(0)) { |(i, v), h| h[v.last] += 1 }
|
|
.max_by(&:last).try(&:first)
|
|
max_value = @nutrients[q].values.max_by { |a, u| a || 0 }.try(&:first) || BigDecimal(0)
|
|
precision = [3 - max_value.exponent, 0].max
|
|
|
|
# TODO: summing up ingredients should take units into account
|
|
@nutrients[q].each do |i, (a, v)|
|
|
meal = i.composition
|
|
@nutrient_summary[q][meal] += a
|
|
@nutrient_summary[q][meal.display_date] += a
|
|
end
|
|
|
|
@nutrients[q][:mfu_unit] = mfu_unit
|
|
@nutrients[q][:precision] = precision
|
|
end
|
|
|
|
@meals_by_date = @project.meals.reject(&:new_record?)
|
|
.sort_by { |m| m.eaten_at || m.created_at }.group_by(&:display_date)
|
|
end
|
|
end
|