Create IngredientAmount class

This class will replace FoodAmount when it has proper support for
calculating nutrients for FoodAmount and Recipe combinations.
This commit is contained in:
Christopher C. Wells 2021-01-22 22:02:20 -08:00
parent ffd635a750
commit 99129e3c76
6 changed files with 171 additions and 2 deletions

View File

@ -0,0 +1,98 @@
<?php
namespace App\Models;
use App\Support\Number;
use App\Support\Nutrients;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class IngredientAmount extends Model
{
use HasFactory;
/**
* @inheritdoc
*/
protected $fillable = [
'amount',
'unit',
'detail',
'weight',
];
/**
* The attributes that should be cast.
*/
protected $casts = [
'amount' => 'float',
'weight' => 'int',
];
/**
* @inheritdoc
*/
protected $with = ['ingredient'];
/**
* Nutrient calculation methods.
*/
private array $nutrientMethods = [
'calories',
'carbohydrates',
'cholesterol',
'fat',
'protein',
'sodium',
];
/**
* @inheritdoc
*/
protected $appends = ['amount_formatted'];
/**
* Get the amount as a formatted string (e.g. 0.5 = 1/2).
*/
public function getAmountFormattedAttribute(): string {
return Number::fractionStringFromFloat($this->amount);
}
/**
* Get the ingredient type (Food or Recipe).
*/
public function ingredient(): BelongsTo {
return $this->morphTo();
}
/**
* Get the parent (Recipe or JournalEntry).
*/
public function parent(): BelongsTo {
return $this->morphTo();
}
/**
* Add nutrient calculations handling to overloading.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*
* @noinspection PhpMissingParamTypeInspection
*/
public function __call($method, $parameters): mixed {
if (in_array($method, $this->nutrientMethods)) {
return $this->ingredient->{$method} * Nutrients::calculateFoodNutrientMultiplier(
$this->ingredient,
$this->amount,
$this->unit
);
}
else {
return parent::__call($method, $parameters);
}
}
}

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Models\Traits\HasIngredients;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -48,7 +49,7 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
*/ */
class JournalEntry extends Model class JournalEntry extends Model
{ {
use HasFactory; use HasFactory, HasIngredients;
/** /**
* @inheritdoc * @inheritdoc

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Models\Traits\HasIngredients;
use App\Models\Traits\Ingredient; use App\Models\Traits\Ingredient;
use App\Models\Traits\Journalable; use App\Models\Traits\Journalable;
use App\Models\Traits\Sluggable; use App\Models\Traits\Sluggable;
@ -42,7 +43,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
*/ */
class Recipe extends Model class Recipe extends Model
{ {
use HasFactory, Ingredient, Journalable, Sluggable; use HasFactory, HasIngredients, Ingredient, Journalable, Sluggable;
/** /**
* @inheritdoc * @inheritdoc
@ -85,6 +86,11 @@ class Recipe extends Model
'sodiumPerServing', 'sodiumPerServing',
]; ];
/**
* @inheritdoc
*/
protected $with = ['ingredients'];
/** /**
* Get the steps for this Recipe. * Get the steps for this Recipe.
*/ */

View File

@ -0,0 +1,16 @@
<?php
namespace App\Models\Traits;
use App\Models\IngredientAmount;
use Illuminate\Database\Eloquent\Relations\MorphMany;
trait HasIngredients
{
/**
* Get all of the ingredients.
*/
public function ingredients(): MorphMany {
return $this->morphMany(IngredientAmount::class, 'parent');
}
}

View File

@ -2,10 +2,19 @@
namespace App\Models\Traits; namespace App\Models\Traits;
use App\Models\IngredientAmount;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Support\Collection; 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

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateIngredientAmountsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('ingredient_amounts', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('ingredient_id');
$table->string('ingredient_type');
$table->unsignedFloat('amount');
$table->enum('unit', ['tsp', 'tbsp', 'cup', 'oz', 'gram', 'serving'])->nullable();
$table->string('detail')->nullable();
$table->unsignedInteger('weight');
$table->unsignedInteger('parent_id');
$table->string('parent_type');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('ingredient_amounts');
}
}