Refactor Recipe to support IngredientAmount (WIP)

Only Food IngredientAmounts are supported currently.
This commit is contained in:
Christopher C. Wells 2021-01-22 23:46:12 -08:00 committed by Christopher Charbonneau Wells
parent 2dfc9b457c
commit 670d6127ca
7 changed files with 30 additions and 42 deletions

View File

@ -2,7 +2,8 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\FoodAmount; use App\Models\Food;
use App\Models\IngredientAmount;
use App\Models\Recipe; use App\Models\Recipe;
use App\Models\RecipeStep; use App\Models\RecipeStep;
use App\Rules\ArrayNotEmpty; use App\Rules\ArrayNotEmpty;
@ -73,29 +74,29 @@ class RecipeController extends Controller
// Pre-populate relationships from form data or current recipe. // Pre-populate relationships from form data or current recipe.
$ingredients = []; $ingredients = [];
if ($old = old('ingredients')) { if ($old = old('ingredients')) {
foreach ($old['id'] as $key => $food_id) { foreach ($old['id'] as $key => $ingredient_id) {
if (empty($food_id)) { if (empty($ingredient_id)) {
continue; continue;
} }
$ingredients[] = [ $ingredients[] = [
'original_key' => $old['original_key'][$key], 'original_key' => $old['original_key'][$key],
'amount' => $old['amount'][$key], 'amount' => $old['amount'][$key],
'unit' => $old['unit'][$key], 'unit' => $old['unit'][$key],
'food_id' => $food_id, 'ingredient_id' => $ingredient_id,
'food_name' => $old['name'][$key], 'ingredient_name' => $old['name'][$key],
'detail' => $old['detail'][$key], 'detail' => $old['detail'][$key],
]; ];
} }
} }
else { else {
foreach ($recipe->foodAmounts as $key => $foodAmount) { foreach ($recipe->ingredientAmounts as $key => $ingredientAmount) {
$ingredients[] = [ $ingredients[] = [
'original_key' => $key, 'original_key' => $key,
'amount' => $foodAmount->amount_formatted, 'amount' => $ingredientAmount->amount_formatted,
'unit' => $foodAmount->unit, 'unit' => $ingredientAmount->unit,
'food_id' => $foodAmount->food->id, 'ingredient_id' => $ingredientAmount->ingredient->id,
'food_name' => $foodAmount->food->name, 'ingredient_name' => $ingredientAmount->ingredient->name,
'detail' => $foodAmount->detail, 'detail' => $ingredientAmount->detail,
]; ];
} }
} }
@ -158,7 +159,7 @@ class RecipeController extends Controller
'ingredients.detail' => ['required', 'array'], 'ingredients.detail' => ['required', 'array'],
'ingredients.detail.*' => 'nullable|string', 'ingredients.detail.*' => 'nullable|string',
'ingredients.id' => ['required', 'array', new ArrayNotEmpty], 'ingredients.id' => ['required', 'array', new ArrayNotEmpty],
'ingredients.id.*' => 'required_with:ingredients.amount.*|nullable|exists:App\Models\Food,id', 'ingredients.id.*' => 'required_with:ingredients.amount.*|nullable',
'ingredients.original_key' => 'nullable|array', 'ingredients.original_key' => 'nullable|array',
'steps.step' => ['required', 'array', new ArrayNotEmpty], 'steps.step' => ['required', 'array', new ArrayNotEmpty],
'steps.step.*' => 'nullable|string', 'steps.step.*' => 'nullable|string',
@ -179,30 +180,31 @@ class RecipeController extends Controller
} }
// Delete any removed ingredients. // Delete any removed ingredients.
$removed = array_diff($recipe->foodAmounts->keys()->all(), $input['ingredients']['original_key']); $removed = array_diff($recipe->ingredientAmounts->keys()->all(), $input['ingredients']['original_key']);
foreach ($removed as $removed_key) { foreach ($removed as $removed_key) {
$recipe->foodAmounts[$removed_key]->delete(); $recipe->ingredientAmounts[$removed_key]->delete();
} }
// Add/update current ingredients. // Add/update current ingredients.
$food_amounts = []; $ingredient_amounts = [];
$weight = 0; $weight = 0;
foreach (array_filter($input['ingredients']['id']) as $key => $food_id) { foreach (array_filter($input['ingredients']['id']) as $key => $ingredient_id) {
if (!is_null($input['ingredients']['original_key'][$key])) { if (!is_null($input['ingredients']['original_key'][$key])) {
$food_amounts[$key] = $recipe->foodAmounts[$input['ingredients']['original_key'][$key]]; $ingredient_amounts[$key] = $recipe->ingredientAmounts[$input['ingredients']['original_key'][$key]];
} }
else { else {
$food_amounts[$key] = new FoodAmount(); $ingredient_amounts[$key] = new IngredientAmount();
} }
$food_amounts[$key]->fill([ $ingredient_amounts[$key]->fill([
'amount' => Number::floatFromString($input['ingredients']['amount'][$key]), 'amount' => Number::floatFromString($input['ingredients']['amount'][$key]),
'unit' => $input['ingredients']['unit'][$key], 'unit' => $input['ingredients']['unit'][$key],
'detail' => $input['ingredients']['detail'][$key], 'detail' => $input['ingredients']['detail'][$key],
'weight' => $weight++, 'weight' => $weight++,
]); ]);
$food_amounts[$key]->food()->associate($food_id); $ingredient_amounts[$key]->ingredient()
->associate(Food::where('id', $ingredient_id)->first());
} }
$recipe->foodAmounts()->saveMany($food_amounts); $recipe->ingredientAmounts()->saveMany($ingredient_amounts);
$steps = []; $steps = [];
$number = 1; $number = 1;

View File

@ -51,7 +51,7 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
*/ */
class JournalEntry extends Model class JournalEntry extends Model
{ {
use HasFactory, HasIngredients; use HasFactory;
/** /**
* @inheritdoc * @inheritdoc

View File

@ -81,7 +81,7 @@ class Recipe extends Model
/** /**
* @inheritdoc * @inheritdoc
*/ */
protected $with = ['ingredients']; protected $with = ['ingredientAmounts'];
/** /**
* Get the steps for this Recipe. * Get the steps for this Recipe.
@ -90,13 +90,6 @@ class Recipe extends Model
return $this->hasMany(RecipeStep::class)->orderBy('number'); return $this->hasMany(RecipeStep::class)->orderBy('number');
} }
/**
* Get the Food Amounts used for this Recipe.
*/
public function foodAmounts(): HasMany {
return $this->hasMany(FoodAmount::class)->orderBy('weight');
}
/** /**
* Add nutrient calculations handling to overloading. * Add nutrient calculations handling to overloading.
* *

View File

@ -22,7 +22,7 @@ trait HasIngredients
/** /**
* Get all of the ingredients. * Get all of the ingredients.
*/ */
public function ingredients(): MorphMany { public function ingredientAmounts(): MorphMany {
return $this->morphMany(IngredientAmount::class, 'parent'); return $this->morphMany(IngredientAmount::class, 'parent');
} }

View File

@ -8,13 +8,6 @@ use Illuminate\Support\Collection;
trait Ingredient trait Ingredient
{ {
/**
* Get all of the ingredient amounts for this ingredient.
*/
public function ingredientAmounts(): MorphToMany {
return $this->morphToMany(IngredientAmount::class, 'ingredient');
}
/** /**
* Gets search results for a term. * Gets search results for a term.
*/ */

View File

@ -9,8 +9,8 @@
:selectedValue="$unit ?? null"> :selectedValue="$unit ?? null">
<option value=""></option> <option value=""></option>
</x-inputs.select> </x-inputs.select>
<x-ingredient-picker :default-id="$food_id ?? null" <x-ingredient-picker :default-id="$ingredient_id ?? null"
:default-name="$food_name ?? null" /> :default-name="$ingredient_name ?? null" />
<x-inputs.input type="text" <x-inputs.input type="text"
class="block" class="block"
name="ingredients[detail][]" name="ingredients[detail][]"

View File

@ -22,11 +22,11 @@
<h3 class="mb-2 font-bold">Description</h3> <h3 class="mb-2 font-bold">Description</h3>
<div class="mb-2 text-gray-800">{{ $recipe->description }}</div> <div class="mb-2 text-gray-800">{{ $recipe->description }}</div>
<h3 class="mb-2 font-bold">Ingredients</h3> <h3 class="mb-2 font-bold">Ingredients</h3>
@foreach($recipe->foodAmounts as $ia) @foreach($recipe->ingredientAmounts as $ia)
<div class="flex flex-row space-x-2 mb-2"> <div class="flex flex-row space-x-2 mb-2">
<div>{{ \App\Support\Number::fractionStringFromFloat($ia->amount) }}</div> <div>{{ \App\Support\Number::fractionStringFromFloat($ia->amount) }}</div>
@if($ia->unit)<div>{{ $ia->unit }}</div>@endif @if($ia->unit)<div>{{ $ia->unit }}</div>@endif
<div>{{ $ia->food->name }}</div> <div>{{ $ia->ingredient->name }}</div>
@if($ia->detail)<div class="text-gray-500">{{ $ia->detail }}</div>@endif @if($ia->detail)<div class="text-gray-500">{{ $ia->detail }}</div>@endif
</div> </div>
@endforeach @endforeach