Refactor on base 100g unit

This commit is contained in:
Christopher C. Wells 2020-12-22 14:41:45 -08:00
parent 2d1990d415
commit 013baa88fc
8 changed files with 107 additions and 68 deletions

View File

@ -7,12 +7,14 @@ use Illuminate\Database\Eloquent\Model;
/**
* @property int id
* @property string name
* @property string unit
* @property float calories
* @property float protein
* @property float fat
* @property float carbohydrates
* @property string name Ingredient base name.
* @property ?string detail Some additional detail about the ingredient (e.g. "small" with the name "onion").
* @property float calories (per 100g).
* @property float protein (per 100g).
* @property float fat (per 100g).
* @property float carbohydrates (per 100g).
* @property ?float unit_weight Weight of one cup of the ingredient.
* @property ?float cup_weight Weight of one "unit" (e.g. an egg, onion, etc.) of the ingredient.
*/
class Ingredient extends Model
{
@ -23,10 +25,24 @@ class Ingredient extends Model
*/
protected array $fillable = [
'name',
'unit',
'detail',
'calories',
'protein',
'fat',
'carbohydrates',
'unitWeight',
'cupWeight',
];
/**
* The attributes that should be cast.
*/
protected array $casts = [
'calories' => 'float',
'protein' => 'float',
'fat' => 'float',
'carbohydrates' => 'float',
'unit_weight' => 'float',
'cup_weight' => 'float',
];
}

View File

@ -8,9 +8,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property int id
* @property float amount
* @property float unit
* @property int weight
* @property float amount Amount of ingredient.
* @property ?string unit Ingredient unit (tsp, tbsp, cup, or grams).
* @property int weight Weight of ingredient in full ingredient list (lowest first).
* @property \App\Models\Ingredient ingredient
* @property \App\Models\Recipe recipe
*/
@ -27,6 +27,14 @@ class IngredientAmount extends Model
'weight',
];
/**
* The attributes that should be cast.
*/
protected array $casts = [
'amount' => 'float',
'weight' => 'int',
];
/**
* @inheritdoc
*/
@ -50,42 +58,39 @@ class IngredientAmount extends Model
* Get total calories for the ingredient amount.
*/
public function calories(): float {
return $this->ingredient->calories * $this->amount * $this->unitMultiplier();
return $this->ingredient->calories * $this->unitMultiplier();
}
/**
* Get total protein for the ingredient amount.
*/
public function protein(): float {
return $this->ingredient->protein * $this->amount * $this->unitMultiplier();
return $this->ingredient->protein * $this->unitMultiplier();
}
/**
* Get total fat for the ingredient amount.
*/
public function fat(): float {
return $this->ingredient->fat * $this->amount * $this->unitMultiplier();
return $this->ingredient->fat * $this->unitMultiplier();
}
/**
* Get total carbohydrates for the ingredient amount.
*/
public function carbohydrates(): float {
return $this->ingredient->carbohydrates * $this->amount * $this->unitMultiplier();
return $this->ingredient->carbohydrates * $this->unitMultiplier();
}
/**
* Get the multiplier for the ingredient unit and ingredient amount unit.
* Get the multiplier for the ingredient unit based on weight.
*/
private function unitMultiplier(): float {
return match (true) {
$this->ingredient->unit === 'tsp' && $this->unit === 'tbsp' => 3,
$this->ingredient->unit === 'tsp' && $this->unit === 'cup' => 48,
$this->ingredient->unit === 'tbsp' && $this->unit === 'tsp' => 1/3,
$this->ingredient->unit === 'tbsp' && $this->unit === 'cup' => 16,
$this->ingredient->unit === 'cup' && $this->unit === 'tsp' => 1/48,
$this->ingredient->unit === 'cup' && $this->unit === 'tbsp' => 1/16,
return match ($this->unit) {
null => $this->ingredient->unit_weight,
'tsp' => 1/48,
'tbsp' => 1/16,
default => 1
};
} * $this->amount * ($this->ingredient->cup_weight ?? 1) / 100;
}
}

View File

@ -26,6 +26,13 @@ class Recipe extends Model
'servings',
];
/**
* The attributes that should be cast.
*/
protected array $casts = [
'servings' => 'int',
];
/**
* @inheritdoc
*/
@ -48,28 +55,28 @@ class Recipe extends Model
/**
* Get total recipe calories.
*/
public function calories(): float {
public function caloriesTotal(): float {
return $this->sumNutrient('calories');
}
/**
* Get total recipe protein.
*/
public function protein(): float {
public function proteinTotal(): float {
return $this->sumNutrient('protein');
}
/**
* Get total recipe fat.
*/
public function fat(): float {
public function fatTotal(): float {
return $this->sumNutrient('fat');
}
/**
* Get total recipe carbohydrates.
*/
public function carbohydrates(): float {
public function carbohydratesTotal(): float {
return $this->sumNutrient('carbohydrates');
}

View File

@ -24,6 +24,13 @@ class RecipeStep extends Model
'step',
];
/**
* The attributes that should be cast.
*/
protected array $casts = [
'number' => 'int',
];
/**
* Get the Recipe this step belongs to.
*/

View File

@ -8,29 +8,27 @@ class CreateIngredientsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
public function up(): void
{
Schema::create('ingredients', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->enum('unit', ['tsp', 'tbsp', 'cup'])->nullable();
$table->string('detail')->nullable();
$table->unsignedFloat('calories')->default(0);
$table->unsignedFloat('protein')->default(0);
$table->unsignedFloat('fat')->default(0);
$table->unsignedFloat('carbohydrates')->default(0);
$table->unsignedFloat('unit_weight')->nullable();
$table->unsignedFloat('cup_weight')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
public function down(): void
{
Schema::dropIfExists('ingredients');
}

View File

@ -19,7 +19,7 @@ class CreateIngredientAmountsTable extends Migration
$table->id();
$table->foreignIdFor(Ingredient::class);
$table->unsignedFloat('amount');
$table->enum('unit', ['tsp', 'tbsp', 'cup'])->nullable();
$table->enum('unit', ['tsp', 'tbsp', 'cup', 'grams'])->nullable();
$table->foreignIdFor(Recipe::class);
$table->unsignedInteger('weight');
$table->timestamps();

View File

@ -15,58 +15,64 @@ class IngredientSeeder extends Seeder
$default_ingredients = [
[
'name' => 'baking powder',
'unit' => 'tsp',
'calories' => 2.44,
'calories' => 53,
'protein' => 0,
'fat' => 0,
'carbohydrates' => 1.27
'carbohydrates' => 27.7,
'cup_weight' => 220.8,
],
[
'name' => 'egg',
'calories' => 71.5,
'protein' => 6.28,
'fat' => 4.76,
'carbohydrates' => 0.36
'detail' => 'large',
'calories' => 147,
'protein' => 12.4,
'fat' => 9.96,
'carbohydrates' => 0.96,
'unit_weight' => 50.3,
],
[
'name' => 'flour, all-purpose',
'unit' => 'cup',
'calories' => 455,
'protein' => 12.9,
'fat' => 1.22,
'carbohydrates' => 95.4
'name' => 'flour',
'detail' => 'all-purpose',
'calories' => 364,
'protein' => 10.33,
'fat' => 0.98,
'carbohydrates' => 76.31,
'cup_weight' => 125,
],
[
'name' => 'milk, whole',
'unit' => 'cup',
'calories' => 146,
'protein' => 8,
'fat' => 7.81,
'carbohydrates' => 11.4
'name' => 'milk',
'detail' => 'whole',
'calories' => 60,
'protein' => 3.28,
'fat' => 3.2,
'carbohydrates' => 4.67,
'cup_weight' => 244,
],
[
'name' => 'salt',
'unit' => 'tsp',
'detail' => 'table',
'calories' => 0,
'protein' => 0,
'fat' => 0,
'carbohydrates' => 0
'carbohydrates' => 0,
'cup_weight' => 292,
],
[
'name' => 'sugar, white',
'unit' => 'cup',
'calories' => 770,
'name' => 'sugar',
'detail' => 'white',
'calories' => 385,
'protein' => 0,
'fat' => 0.54,
'carbohydrates' => 199
'fat' => 0.32,
'carbohydrates' => 99.6,
'cup_weight' => 200,
],
[
'name' => 'vegetable oil',
'unit' => 'tbsp',
'calories' => 124,
'calories' => 886,
'protein' => 0,
'fat' => 14,
'carbohydrates' => 199
'fat' => 100,
'carbohydrates' => 0,
'cup_weight' => 224,
],
];
Ingredient::factory()->createMany($default_ingredients);

View File

@ -25,7 +25,7 @@ class RecipeSeeder extends Seeder
$weight = 0;
$amounts = [
[
'ingredient_id' => Ingredient::where('name', 'flour, all-purpose')
'ingredient_id' => Ingredient::where('name', 'flour')
->first()->id,
'amount' => 1,
'unit' => 'cup',
@ -33,7 +33,7 @@ class RecipeSeeder extends Seeder
'weight' => $weight++,
],
[
'ingredient_id' => Ingredient::where('name', 'sugar, white')
'ingredient_id' => Ingredient::where('name', 'sugar')
->first()->id,
'amount' => 2,
'unit' => 'tbsp',
@ -64,7 +64,7 @@ class RecipeSeeder extends Seeder
'weight' => $weight++,
],
[
'ingredient_id' => Ingredient::where('name', 'milk, whole')
'ingredient_id' => Ingredient::where('name', 'milk')
->first()->id,
'amount' => 1,
'unit' => 'cup',